| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Data::MuForm::Fields; |
|
2
|
|
|
|
|
|
|
# ABSTRACT: Common attributes and methods for forms and compound fields |
|
3
|
81
|
|
|
81
|
|
36873
|
use Moo::Role; |
|
|
81
|
|
|
|
|
165
|
|
|
|
81
|
|
|
|
|
385
|
|
|
4
|
|
|
|
|
|
|
|
|
5
|
81
|
|
|
81
|
|
15558
|
use Types::Standard -types; |
|
|
81
|
|
|
|
|
112
|
|
|
|
81
|
|
|
|
|
735
|
|
|
6
|
81
|
|
|
81
|
|
235199
|
use Type::Utils; |
|
|
81
|
|
|
|
|
258995
|
|
|
|
81
|
|
|
|
|
627
|
|
|
7
|
81
|
|
|
81
|
|
72919
|
use Data::Clone ('data_clone'); |
|
|
81
|
|
|
|
|
106
|
|
|
|
81
|
|
|
|
|
3354
|
|
|
8
|
81
|
|
|
81
|
|
3938
|
use Class::Load ('load_optional_class'); |
|
|
81
|
|
|
|
|
84077
|
|
|
|
81
|
|
|
|
|
2973
|
|
|
9
|
81
|
|
|
81
|
|
303
|
use Scalar::Util 'blessed'; |
|
|
81
|
|
|
|
|
98
|
|
|
|
81
|
|
|
|
|
224957
|
|
|
10
|
|
|
|
|
|
|
with 'Data::MuForm::Common'; |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
has 'value' => ( is => 'rw', predicate => 'has_value', default => sub {{}} ); |
|
14
|
133
|
|
|
133
|
0
|
273
|
sub clear_value { $_[0]->{value} = {} } |
|
15
|
7
|
|
|
7
|
0
|
1174
|
sub values { $_[0]->value } |
|
16
|
|
|
|
|
|
|
has 'init_value' => ( is => 'rw', clearer => 'clear_init_value' ); |
|
17
|
|
|
|
|
|
|
has 'input' => ( is => 'rw', clearer => 'clear_input' ); |
|
18
|
|
|
|
|
|
|
has 'skip_fields_without_input' => ( is => 'rw' ); # except 'input_without_param' |
|
19
|
|
|
|
|
|
|
has 'filled_from' => ( is => 'rw', clearer => 'clear_filled_from' ); |
|
20
|
|
|
|
|
|
|
has 'meta_fields' => ( is => 'rw' ); |
|
21
|
|
|
|
|
|
|
has 'field_list' => ( is => 'rw', isa => ArrayRef, lazy => 1, builder => 'build_field_list' ); |
|
22
|
222
|
|
|
222
|
0
|
55242
|
sub build_field_list {[]} |
|
23
|
|
|
|
|
|
|
has 'fields' => ( is => 'rw', isa => ArrayRef, default => sub {[]}); |
|
24
|
1045
|
|
|
1045
|
0
|
1405
|
sub push_field { my ( $self, @fields ) = @_; push @{$self->{fields}}, @fields; } |
|
|
1045
|
|
|
|
|
899
|
|
|
|
1045
|
|
|
|
|
2859
|
|
|
25
|
85
|
|
|
85
|
0
|
88
|
sub clear_fields { my $self = shift; $self->{fields} = undef; } |
|
|
85
|
|
|
|
|
172
|
|
|
26
|
2072
|
|
|
2072
|
0
|
2254
|
sub all_fields { my $self = shift; return @{$self->{fields}}; } |
|
|
2072
|
|
|
|
|
1506
|
|
|
|
2072
|
|
|
|
|
4837
|
|
|
27
|
5
|
|
|
5
|
0
|
9
|
sub set_field_at { my ( $self, $index, $field ) = @_; @{$self->{fields}}[$index] = $field; } |
|
|
5
|
|
|
|
|
7
|
|
|
|
5
|
|
|
|
|
15
|
|
|
28
|
60
|
|
|
60
|
0
|
4940
|
sub num_fields { my $self = shift; return scalar (@{$self->{fields}}); } |
|
|
60
|
|
|
|
|
74
|
|
|
|
60
|
|
|
|
|
333
|
|
|
29
|
775
|
|
|
775
|
0
|
693
|
sub has_fields { my $self = shift; return scalar (@{$self->{fields}}); } |
|
|
775
|
|
|
|
|
627
|
|
|
|
775
|
|
|
|
|
3301
|
|
|
30
|
|
|
|
|
|
|
has 'error_fields' => ( is => 'rw', isa => ArrayRef, default => sub {[]} ); |
|
31
|
308
|
|
|
308
|
0
|
477
|
sub clear_error_fields { $_[0]->{error_fields} = [] } |
|
32
|
375
|
|
|
375
|
0
|
303
|
sub has_error_fields { my $self = shift; return scalar @{$self->error_fields}; } |
|
|
375
|
|
|
|
|
272
|
|
|
|
375
|
|
|
|
|
777
|
|
|
33
|
9
|
|
|
9
|
0
|
748
|
sub num_error_fields { my $self = shift; return scalar @{$self->error_fields}; } |
|
|
9
|
|
|
|
|
10
|
|
|
|
9
|
|
|
|
|
51
|
|
|
34
|
81
|
|
|
81
|
0
|
85
|
sub add_error_field { my ($self, $field) = @_; push @{$self->error_fields}, $field; } |
|
|
81
|
|
|
|
|
91
|
|
|
|
81
|
|
|
|
|
294
|
|
|
35
|
8
|
|
|
8
|
0
|
11
|
sub all_error_fields { my $self = shift; return @{$self->error_fields}; } |
|
|
8
|
|
|
|
|
135
|
|
|
|
8
|
|
|
|
|
25
|
|
|
36
|
|
|
|
|
|
|
has 'field_namespace' => ( |
|
37
|
|
|
|
|
|
|
is => 'rw', |
|
38
|
|
|
|
|
|
|
isa => ArrayRef, |
|
39
|
|
|
|
|
|
|
builder => 'build_field_namespace', |
|
40
|
|
|
|
|
|
|
coerce => sub { |
|
41
|
|
|
|
|
|
|
my $ns = shift; |
|
42
|
|
|
|
|
|
|
return [] unless defined $ns; |
|
43
|
|
|
|
|
|
|
return $ns if ref $ns eq 'ARRAY'; |
|
44
|
|
|
|
|
|
|
return [$ns] if length($ns); |
|
45
|
|
|
|
|
|
|
return []; |
|
46
|
|
|
|
|
|
|
}, |
|
47
|
|
|
|
|
|
|
); |
|
48
|
128
|
|
|
128
|
0
|
3183
|
sub build_field_namespace { [] } |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub subfield { |
|
51
|
8
|
|
|
8
|
0
|
50
|
my ( $self, $name ) = @_; |
|
52
|
8
|
|
|
|
|
21
|
return $self->field($name, $self); |
|
53
|
|
|
|
|
|
|
} |
|
54
|
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
sub field { |
|
56
|
511
|
|
|
511
|
0
|
70581
|
my ( $self, $name, $f ) = @_; |
|
57
|
|
|
|
|
|
|
|
|
58
|
511
|
|
|
|
|
488
|
my $index; |
|
59
|
|
|
|
|
|
|
# if this is a full_name for a compound field |
|
60
|
|
|
|
|
|
|
# walk through the fields to get to it |
|
61
|
511
|
50
|
|
|
|
940
|
return undef unless ( defined $name ); |
|
62
|
511
|
100
|
66
|
|
|
2134
|
if( $self->form && $self == $self->form && |
|
|
|
|
66
|
|
|
|
|
|
63
|
|
|
|
|
|
|
exists $self->index->{$name} ) { |
|
64
|
432
|
|
|
|
|
35413
|
return $self->index->{$name}; |
|
65
|
|
|
|
|
|
|
} |
|
66
|
79
|
100
|
|
|
|
2012
|
if ( $name =~ /\./ ) { |
|
67
|
12
|
|
|
|
|
73
|
my @names = split /\./, $name; |
|
68
|
12
|
|
33
|
|
|
61
|
$f ||= $self->form || $self; |
|
|
|
|
66
|
|
|
|
|
|
69
|
12
|
|
|
|
|
25
|
foreach my $fname (@names) { |
|
70
|
30
|
|
|
|
|
87
|
$f = $f->field($fname); |
|
71
|
30
|
50
|
|
|
|
96
|
return unless $f; |
|
72
|
|
|
|
|
|
|
} |
|
73
|
12
|
|
|
|
|
84
|
return $f; |
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
else # not a compound name |
|
76
|
|
|
|
|
|
|
{ |
|
77
|
67
|
|
|
|
|
136
|
for my $field ( $self->all_fields ) { |
|
78
|
96
|
100
|
|
|
|
482
|
return $field if ( $field->name eq $name ); |
|
79
|
|
|
|
|
|
|
} |
|
80
|
|
|
|
|
|
|
} |
|
81
|
2
|
|
|
|
|
10
|
return; |
|
82
|
|
|
|
|
|
|
} |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub all_sorted_fields { |
|
85
|
760
|
|
|
760
|
0
|
1754
|
my $self = shift; |
|
86
|
2043
|
|
|
|
|
3565
|
my @fields = sort { $a->order <=> $b->order } |
|
87
|
760
|
|
|
|
|
1296
|
grep { $_->is_active } $self->all_fields; |
|
|
2130
|
|
|
|
|
4414
|
|
|
88
|
760
|
|
|
|
|
2346
|
return @fields; |
|
89
|
|
|
|
|
|
|
} |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub sorted_fields { |
|
92
|
8
|
|
|
8
|
0
|
68
|
my $self = shift; |
|
93
|
8
|
|
|
|
|
21
|
my @fields = $self->all_sorted_fields; |
|
94
|
8
|
|
|
|
|
40
|
return \@fields; |
|
95
|
|
|
|
|
|
|
} |
|
96
|
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
sub field_index { |
|
98
|
581
|
|
|
581
|
0
|
793
|
my ( $self, $name ) = @_; |
|
99
|
581
|
|
|
|
|
579
|
my $index = 0; |
|
100
|
581
|
|
|
|
|
1494
|
for my $field ( $self->all_fields ) { |
|
101
|
898
|
100
|
|
|
|
2178
|
return $index if $field->name eq $name; |
|
102
|
891
|
|
|
|
|
819
|
$index++; |
|
103
|
|
|
|
|
|
|
} |
|
104
|
574
|
|
|
|
|
757
|
return; |
|
105
|
|
|
|
|
|
|
} |
|
106
|
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
# Repeatable overrides this |
|
108
|
|
|
|
|
|
|
sub fields_validate { |
|
109
|
152
|
|
|
152
|
0
|
158
|
my $self = shift; |
|
110
|
|
|
|
|
|
|
|
|
111
|
152
|
50
|
|
|
|
292
|
return unless $self->has_fields; |
|
112
|
|
|
|
|
|
|
# validate all fields |
|
113
|
152
|
|
|
|
|
235
|
my %value_hash; |
|
114
|
152
|
|
|
|
|
551
|
foreach my $field ( $self->all_sorted_fields ) { |
|
115
|
438
|
100
|
66
|
|
|
1381
|
next if ( !$field->is_active || $field->disabled ); |
|
116
|
436
|
100
|
100
|
|
|
1346
|
next if ( $self->skip_fields_without_input && ! $field->has_input && ! $field->has_input_without_param ); |
|
|
|
|
66
|
|
|
|
|
|
117
|
|
|
|
|
|
|
# Validate each field and "inflate" input -> value. |
|
118
|
429
|
|
|
|
|
1220
|
$field->field_validate; # this calls all the various validation routines |
|
119
|
429
|
100
|
100
|
|
|
28170
|
$value_hash{ $field->accessor } = $field->value |
|
120
|
|
|
|
|
|
|
if ( $field->has_value && !$field->no_update ); |
|
121
|
|
|
|
|
|
|
} |
|
122
|
152
|
|
|
|
|
1058
|
$self->value( \%value_hash ); |
|
123
|
|
|
|
|
|
|
} |
|
124
|
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
sub fields_fif { |
|
126
|
111
|
|
|
111
|
0
|
141
|
my ( $self, $prefix ) = @_; |
|
127
|
|
|
|
|
|
|
|
|
128
|
111
|
|
100
|
|
|
350
|
$prefix ||= ''; |
|
129
|
111
|
100
|
100
|
|
|
754
|
$prefix = $self->field_prefix . "." |
|
130
|
|
|
|
|
|
|
if ( $self->isa('Data::MuForm') && $self->field_prefix ); |
|
131
|
|
|
|
|
|
|
|
|
132
|
111
|
|
|
|
|
104
|
my %params; |
|
133
|
111
|
|
|
|
|
206
|
foreach my $field ( $self->all_sorted_fields ) { |
|
134
|
296
|
100
|
33
|
|
|
459
|
next if ( ! $field->is_active || $field->password || $field->no_fif ); |
|
|
|
|
66
|
|
|
|
|
|
135
|
289
|
|
|
|
|
633
|
my $fif = $field->fif; |
|
136
|
289
|
100
|
100
|
|
|
845
|
next if ( !defined $fif || (ref $fif eq 'ARRAY' && ! scalar @{$fif} ) ); |
|
|
19
|
|
33
|
|
|
57
|
|
|
137
|
288
|
100
|
|
|
|
456
|
if ( $field->has_fields ) { |
|
138
|
|
|
|
|
|
|
# this builds up foo.0.bar.name |
|
139
|
53
|
|
|
|
|
281
|
my $next_params = $field->fields_fif( $prefix . $field->name . '.' ); |
|
140
|
53
|
50
|
|
|
|
92
|
next unless $next_params; |
|
141
|
53
|
|
|
|
|
71
|
%params = ( %params, %{$next_params} ); |
|
|
53
|
|
|
|
|
444
|
|
|
142
|
|
|
|
|
|
|
} |
|
143
|
|
|
|
|
|
|
else { |
|
144
|
235
|
|
|
|
|
622
|
$params{ $prefix . $field->name } = $fif; |
|
145
|
|
|
|
|
|
|
} |
|
146
|
|
|
|
|
|
|
} |
|
147
|
111
|
50
|
|
|
|
367
|
return if !%params; |
|
148
|
111
|
|
|
|
|
349
|
return \%params; |
|
149
|
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
} |
|
151
|
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
sub fields_get_results { |
|
153
|
1
|
|
|
1
|
0
|
1
|
my $self = shift; |
|
154
|
|
|
|
|
|
|
|
|
155
|
1
|
|
|
|
|
5
|
my $result = $self->get_result; |
|
156
|
1
|
|
|
|
|
2
|
my @field_results; |
|
157
|
1
|
|
|
|
|
3
|
foreach my $field ( $self->all_sorted_fields ) { |
|
158
|
2
|
50
|
|
|
|
7
|
next if ! $field->is_active; |
|
159
|
2
|
|
|
|
|
7
|
my $result = $field->get_result; |
|
160
|
2
|
|
|
|
|
4
|
push @field_results, $result; |
|
161
|
|
|
|
|
|
|
} |
|
162
|
1
|
|
|
|
|
4
|
$result->{fields} = \@field_results; |
|
163
|
1
|
|
|
|
|
3
|
return $result; |
|
164
|
|
|
|
|
|
|
} |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
#==================================================================== |
|
167
|
|
|
|
|
|
|
# Build Fields |
|
168
|
|
|
|
|
|
|
#==================================================================== |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
sub build_fields { |
|
171
|
228
|
|
|
228
|
0
|
330
|
my $self = shift; |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
# process meta fields |
|
174
|
228
|
|
|
|
|
4122
|
my @meta_fields = $self->_meta_fields; |
|
175
|
228
|
|
|
|
|
4705
|
$self->meta_fields(\@meta_fields); |
|
176
|
228
|
|
|
|
|
3693
|
my $meta_fields = data_clone(\@meta_fields); |
|
177
|
228
|
|
|
|
|
1122
|
$self->process_field_array( $meta_fields ); |
|
178
|
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
# process field_list |
|
180
|
227
|
|
|
|
|
1290
|
my $field_list = $self->field_list; |
|
181
|
227
|
100
|
100
|
|
|
5567
|
$field_list = $self->convert_field_list_to_hashes($field_list) |
|
182
|
|
|
|
|
|
|
if $field_list->[0] && ref($field_list->[0]) ne 'HASH'; |
|
183
|
227
|
|
|
|
|
1552
|
$self->process_field_array ( $field_list ); |
|
184
|
|
|
|
|
|
|
|
|
185
|
227
|
100
|
|
|
|
1090
|
return unless $self->has_fields; |
|
186
|
147
|
|
|
|
|
1513
|
$self->order_fields; |
|
187
|
|
|
|
|
|
|
} |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
sub convert_field_list_to_hashes { |
|
190
|
3
|
|
|
3
|
0
|
5
|
my ( $self, $field_list ) = @_; |
|
191
|
|
|
|
|
|
|
|
|
192
|
3
|
|
|
|
|
5
|
my @new_fields; |
|
193
|
3
|
|
|
|
|
8
|
while (@$field_list) { |
|
194
|
8
|
|
|
|
|
65
|
my $name = shift @$field_list; |
|
195
|
8
|
|
|
|
|
10
|
my $attr = shift @$field_list; |
|
196
|
8
|
100
|
|
|
|
18
|
unless ( ref $attr eq 'HASH' ) { |
|
197
|
4
|
|
|
|
|
9
|
$attr = { type => $attr }; |
|
198
|
|
|
|
|
|
|
} |
|
199
|
8
|
|
|
|
|
30
|
push @new_fields, { name => $name, %$attr }; |
|
200
|
|
|
|
|
|
|
} |
|
201
|
3
|
|
|
|
|
7
|
return \@new_fields; |
|
202
|
|
|
|
|
|
|
} |
|
203
|
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
sub process_field_array { |
|
205
|
455
|
|
|
455
|
0
|
580
|
my ( $self, $fields ) = @_; |
|
206
|
|
|
|
|
|
|
|
|
207
|
455
|
|
|
|
|
1332
|
$fields = $self->clean_fields($fields); |
|
208
|
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
# TODO: there's got to be a better way of doing this |
|
210
|
455
|
|
|
|
|
719
|
my $num_fields = scalar @$fields; |
|
211
|
455
|
|
|
|
|
407
|
my $num_dots = 0; |
|
212
|
455
|
|
|
|
|
1237
|
my $count_fields = 0; |
|
213
|
455
|
|
|
|
|
1077
|
while ( $count_fields < $num_fields ) { |
|
214
|
194
|
|
|
|
|
342
|
foreach my $field (@$fields) { |
|
215
|
882
|
|
|
|
|
1424
|
my $count = ( $field->{name} =~ tr/\.// ); |
|
216
|
882
|
100
|
|
|
|
1592
|
next unless $count == $num_dots; |
|
217
|
580
|
|
|
|
|
2298
|
$self->_make_field($field); |
|
218
|
579
|
|
|
|
|
933
|
$count_fields++; |
|
219
|
|
|
|
|
|
|
} |
|
220
|
193
|
|
|
|
|
2212
|
$num_dots++; |
|
221
|
|
|
|
|
|
|
} |
|
222
|
|
|
|
|
|
|
} |
|
223
|
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
has 'include' => ( is => 'rw', builder => 'build_include', lazy => 1 ); |
|
225
|
225
|
|
|
225
|
0
|
29264
|
sub build_include { [] } |
|
226
|
|
|
|
|
|
|
sub has_include { |
|
227
|
455
|
|
|
455
|
0
|
505
|
my $self = shift; |
|
228
|
455
|
|
50
|
|
|
1497
|
my $include = $self->include || []; |
|
229
|
455
|
|
|
|
|
5372
|
return scalar @{$include}; |
|
|
455
|
|
|
|
|
1072
|
|
|
230
|
|
|
|
|
|
|
} |
|
231
|
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
sub clean_fields { |
|
233
|
455
|
|
|
455
|
0
|
482
|
my ( $self, $fields ) = @_; |
|
234
|
455
|
100
|
|
|
|
1441
|
if( $self->has_include ) { |
|
235
|
6
|
|
|
|
|
8
|
my @fields; |
|
236
|
6
|
|
|
|
|
5
|
my %include = map { $_ => 1 } @{ $self->include }; |
|
|
16
|
|
|
|
|
124
|
|
|
|
6
|
|
|
|
|
13
|
|
|
237
|
6
|
|
|
|
|
13
|
foreach my $fld ( @$fields ) { |
|
238
|
16
|
100
|
|
|
|
46
|
push @fields, data_clone($fld) if exists $include{$fld->{name}}; |
|
239
|
|
|
|
|
|
|
} |
|
240
|
6
|
|
|
|
|
13
|
return \@fields; |
|
241
|
|
|
|
|
|
|
} |
|
242
|
449
|
|
|
|
|
3989
|
return data_clone( $fields ); |
|
243
|
|
|
|
|
|
|
}; |
|
244
|
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
sub _make_field { |
|
246
|
582
|
|
|
582
|
|
630
|
my ( $self, $field_attr ) = @_; |
|
247
|
|
|
|
|
|
|
|
|
248
|
582
|
|
100
|
|
|
1933
|
my $type = $field_attr->{type} ||= 'Text'; |
|
249
|
582
|
|
|
|
|
630
|
my $name = $field_attr->{name}; |
|
250
|
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
# check for a field prefixed with '+', that overrides |
|
252
|
582
|
|
|
|
|
492
|
my $do_update; |
|
253
|
582
|
100
|
|
|
|
1226
|
if ( $name =~ /^\+(.*)/ ) { |
|
254
|
4
|
|
|
|
|
8
|
$field_attr->{name} = $name = $1; |
|
255
|
4
|
|
|
|
|
7
|
$do_update = 1; |
|
256
|
|
|
|
|
|
|
} |
|
257
|
|
|
|
|
|
|
|
|
258
|
582
|
|
|
|
|
1395
|
my $class = $self->_find_field_class( $type, $name ); |
|
259
|
|
|
|
|
|
|
|
|
260
|
582
|
|
|
|
|
1841
|
my $parent = $self->_find_parent( $field_attr ); |
|
261
|
|
|
|
|
|
|
|
|
262
|
581
|
|
|
|
|
1522
|
my $field = $self->_update_or_create( $parent, $field_attr, $class, $do_update ); |
|
263
|
|
|
|
|
|
|
|
|
264
|
581
|
100
|
|
|
|
3062
|
$self->form->add_to_index( $field->full_name => $field ) if $self->form; |
|
265
|
|
|
|
|
|
|
|
|
266
|
581
|
|
|
|
|
1153
|
return $field; |
|
267
|
|
|
|
|
|
|
} |
|
268
|
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
sub _find_field_class { |
|
270
|
582
|
|
|
582
|
|
713
|
my ( $self, $type, $name ) = @_; |
|
271
|
|
|
|
|
|
|
|
|
272
|
582
|
|
|
|
|
2525
|
my $field_ns = $self->field_namespace; |
|
273
|
582
|
|
|
|
|
56696
|
my @classes; |
|
274
|
|
|
|
|
|
|
# '+'-prefixed fields could be full namespaces |
|
275
|
582
|
100
|
|
|
|
1496
|
if ( $type =~ s/^\+// ) { |
|
276
|
13
|
|
|
|
|
20
|
push @classes, $type; |
|
277
|
|
|
|
|
|
|
} |
|
278
|
582
|
|
|
|
|
971
|
foreach my $ns ( @$field_ns, 'Data::MuForm::Field' ) { |
|
279
|
593
|
|
|
|
|
1568
|
push @classes, $ns . "::" . $type; |
|
280
|
|
|
|
|
|
|
} |
|
281
|
|
|
|
|
|
|
# look for Field in possible namespaces |
|
282
|
582
|
|
|
|
|
546
|
my $class; |
|
283
|
582
|
|
|
|
|
702
|
foreach my $try ( @classes ) { |
|
284
|
590
|
100
|
|
|
|
4450
|
last if $class = load_optional_class($try) ? $try : undef; |
|
|
|
100
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
} |
|
286
|
582
|
50
|
|
|
|
30244
|
die "Could not load field class '$type' for field '$name'" |
|
287
|
|
|
|
|
|
|
unless $class; |
|
288
|
|
|
|
|
|
|
|
|
289
|
582
|
|
|
|
|
1191
|
return $class; |
|
290
|
|
|
|
|
|
|
} |
|
291
|
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
sub _find_parent { |
|
294
|
582
|
|
|
582
|
|
661
|
my ( $self, $field_attr ) = @_; |
|
295
|
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
# parent and name correction for names with dots |
|
297
|
582
|
|
|
|
|
512
|
my $parent; |
|
298
|
582
|
100
|
100
|
|
|
3272
|
if ( $field_attr->{name} =~ /\./ ) { |
|
|
|
100
|
|
|
|
|
|
|
299
|
121
|
|
|
|
|
377
|
my @names = split /\./, $field_attr->{name}; |
|
300
|
121
|
|
|
|
|
175
|
my $simple_name = pop @names; |
|
301
|
121
|
|
|
|
|
239
|
my $parent_name = join '.', @names; |
|
302
|
|
|
|
|
|
|
# use special 'field' method call that starts from |
|
303
|
|
|
|
|
|
|
# $self, because names aren't always starting from |
|
304
|
|
|
|
|
|
|
# the form |
|
305
|
121
|
|
|
|
|
429
|
$parent = $self->field($parent_name, $self); |
|
306
|
121
|
100
|
|
|
|
663
|
if ($parent) { |
|
307
|
120
|
50
|
|
|
|
692
|
die "The parent of field " . $field_attr->{name} . " is not a Compound Field" |
|
308
|
|
|
|
|
|
|
unless $parent->isa('Data::MuForm::Field::Compound'); |
|
309
|
120
|
|
|
|
|
256
|
$field_attr->{name} = $simple_name; |
|
310
|
|
|
|
|
|
|
} |
|
311
|
|
|
|
|
|
|
else { |
|
312
|
1
|
|
|
|
|
57
|
die "did not find parent for field " . $field_attr->{name}; |
|
313
|
|
|
|
|
|
|
} |
|
314
|
|
|
|
|
|
|
} |
|
315
|
|
|
|
|
|
|
elsif ( !( $self->form && $self == $self->form ) ) { |
|
316
|
|
|
|
|
|
|
# set parent |
|
317
|
61
|
|
|
|
|
1008
|
$parent = $self; |
|
318
|
|
|
|
|
|
|
} |
|
319
|
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
# get full_name |
|
321
|
581
|
|
|
|
|
869
|
my $full_name = $field_attr->{name}; |
|
322
|
|
|
|
|
|
|
$full_name = $parent->full_name . "." . $field_attr->{name} |
|
323
|
581
|
100
|
|
|
|
1374
|
if $parent; |
|
324
|
581
|
|
|
|
|
860
|
$field_attr->{full_name} = $full_name; |
|
325
|
581
|
|
|
|
|
749
|
return $parent; |
|
326
|
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
} |
|
328
|
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
sub _update_or_create { |
|
330
|
581
|
|
|
581
|
|
779
|
my ( $self, $parent, $field_attr, $class, $do_update ) = @_; |
|
331
|
|
|
|
|
|
|
|
|
332
|
581
|
|
66
|
|
|
3263
|
$parent ||= $self->form; |
|
333
|
581
|
|
|
|
|
790
|
$field_attr->{parent} = $parent; |
|
334
|
581
|
|
|
|
|
11150
|
$field_attr->{localizer} = $parent->localizer; |
|
335
|
581
|
|
|
|
|
19099
|
$field_attr->{renderer} = $parent->renderer; |
|
336
|
581
|
100
|
|
|
|
12583
|
$field_attr->{form} = $self->form if $self->form; |
|
337
|
|
|
|
|
|
|
$field_attr->{skip_fields_without_input} = $parent->skip_fields_without_input |
|
338
|
581
|
50
|
66
|
|
|
2481
|
if ! $self->is_form && $self->is_compound && ! exists $field_attr->{skip_fields_without_input}; |
|
|
|
|
66
|
|
|
|
|
|
339
|
581
|
|
|
|
|
1650
|
my $index = $parent->field_index( $field_attr->{name} ); |
|
340
|
581
|
|
|
|
|
547
|
my $field; |
|
341
|
581
|
100
|
|
|
|
938
|
if ( defined $index ) { |
|
342
|
7
|
100
|
|
|
|
15
|
if ($do_update) { # this field started with '+'. Update. |
|
343
|
2
|
|
|
|
|
13
|
$field = $parent->field( $field_attr->{name} ); |
|
344
|
2
|
50
|
|
|
|
12
|
die "Field to update for " . $field_attr->{name} . " not found" |
|
345
|
|
|
|
|
|
|
unless $field; |
|
346
|
2
|
|
|
|
|
6
|
munge_field_attr($field_attr); |
|
347
|
2
|
|
|
|
|
3
|
foreach my $key ( keys %{$field_attr} ) { |
|
|
2
|
|
|
|
|
5
|
|
|
348
|
18
|
100
|
100
|
|
|
1093
|
next if $key eq 'name' || $key eq 'form' || $key eq 'parent' || |
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
349
|
|
|
|
|
|
|
$key eq 'full_name' || $key eq 'type'; |
|
350
|
8
|
50
|
|
|
|
74
|
$field->$key( $field_attr->{$key} ) |
|
351
|
|
|
|
|
|
|
if $field->can($key); |
|
352
|
|
|
|
|
|
|
} |
|
353
|
|
|
|
|
|
|
} |
|
354
|
|
|
|
|
|
|
else { # replace existing field |
|
355
|
5
|
|
|
|
|
22
|
$field = $self->new_field( $class, $field_attr); |
|
356
|
5
|
|
|
|
|
26
|
$parent->set_field_at( $index, $field ); |
|
357
|
|
|
|
|
|
|
} |
|
358
|
|
|
|
|
|
|
} |
|
359
|
|
|
|
|
|
|
else { # new field |
|
360
|
574
|
|
|
|
|
1369
|
$field = $self->new_field( $class, $field_attr); |
|
361
|
574
|
|
|
|
|
2592
|
$parent->push_field($field); |
|
362
|
|
|
|
|
|
|
} |
|
363
|
581
|
100
|
100
|
|
|
8849
|
$field->form->add_repeatable_field($field) |
|
364
|
|
|
|
|
|
|
if ( $field->form && $field->is_repeatable); |
|
365
|
|
|
|
|
|
|
|
|
366
|
581
|
|
|
|
|
1011
|
return $field; |
|
367
|
|
|
|
|
|
|
} |
|
368
|
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
sub new_field { |
|
370
|
603
|
|
|
603
|
0
|
687
|
my ( $self, $class, $field_attr ) = @_; |
|
371
|
|
|
|
|
|
|
# not handling roles |
|
372
|
603
|
|
|
|
|
9085
|
my $field = $class->new(%$field_attr); |
|
373
|
603
|
|
|
|
|
17383
|
return $field; |
|
374
|
|
|
|
|
|
|
} |
|
375
|
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
sub order_fields { |
|
377
|
217
|
|
|
217
|
0
|
1316
|
my $self = shift; |
|
378
|
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
# number all unordered fields by 5 |
|
380
|
217
|
|
|
|
|
1968
|
my $order = 5; |
|
381
|
217
|
|
|
|
|
489
|
foreach my $field ( $self->all_fields ) { |
|
382
|
620
|
100
|
|
|
|
1545
|
if ( $field->has_fields ) { |
|
383
|
71
|
|
|
|
|
228
|
$field->order_fields; |
|
384
|
|
|
|
|
|
|
} |
|
385
|
|
|
|
|
|
|
# fields will default to 0, so we |
|
386
|
|
|
|
|
|
|
# rewrite order if 0 |
|
387
|
620
|
100
|
|
|
|
1759
|
$field->order($order) unless $field->order; |
|
388
|
620
|
|
|
|
|
1517
|
$order += 5; |
|
389
|
|
|
|
|
|
|
} |
|
390
|
|
|
|
|
|
|
} |
|
391
|
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
sub _get_highest_field_order { |
|
393
|
1
|
|
|
1
|
|
9
|
my $self = shift; |
|
394
|
1
|
|
|
|
|
1
|
my $order = 0; |
|
395
|
1
|
|
|
|
|
3
|
foreach my $field ( $self->all_fields ) { |
|
396
|
3
|
100
|
|
|
|
18
|
$order = $field->order if $field->order > $order; |
|
397
|
|
|
|
|
|
|
} |
|
398
|
1
|
|
|
|
|
3
|
return $order; |
|
399
|
|
|
|
|
|
|
} |
|
400
|
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
# This is a special make field that's used in the Repeatable field to |
|
402
|
|
|
|
|
|
|
# create repeatable instances. It skips some of the overhead of _make_field |
|
403
|
|
|
|
|
|
|
# because some of the info can be hardcoded and we don't want to index it. |
|
404
|
|
|
|
|
|
|
sub _make_adhoc_field { |
|
405
|
24
|
|
|
24
|
|
172
|
my ( $self, $class, $field_attr ) = @_; |
|
406
|
24
|
|
|
|
|
51
|
my $field = $self->new_field( $class, $field_attr ); |
|
407
|
24
|
|
|
|
|
60
|
return $field; |
|
408
|
|
|
|
|
|
|
} |
|
409
|
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
#==================================================================== |
|
412
|
|
|
|
|
|
|
# Initialize input/value (InitResult) |
|
413
|
|
|
|
|
|
|
#==================================================================== |
|
414
|
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
# $input here is from the $params passed in on ->process |
|
416
|
|
|
|
|
|
|
sub fill_from_params { |
|
417
|
160
|
|
|
160
|
0
|
206
|
my ( $self, $input, $exists ) = @_; |
|
418
|
|
|
|
|
|
|
|
|
419
|
160
|
|
|
|
|
410
|
$self->filled_from('params'); |
|
420
|
160
|
0
|
33
|
|
|
427
|
return unless ( defined $input || $exists || $self->has_fields ); |
|
|
|
|
33
|
|
|
|
|
|
421
|
|
|
|
|
|
|
# TODO - this will get replaced by setting the actual processed input 14 lines down. |
|
422
|
|
|
|
|
|
|
# Do we need this? Maybe could be used to transform input before processing? |
|
423
|
160
|
|
|
|
|
617
|
$self->transform_and_set_input($input); |
|
424
|
160
|
|
|
|
|
183
|
my $my_input = {}; |
|
425
|
160
|
50
|
|
|
|
436
|
if ( ref $input eq 'HASH' ) { |
|
426
|
160
|
|
|
|
|
421
|
foreach my $field ( $self->all_sorted_fields ) { |
|
427
|
454
|
50
|
|
|
|
789
|
next if ! $field->is_active; |
|
428
|
454
|
|
66
|
|
|
2071
|
my $fname = $field->input_param || $field->name; |
|
429
|
454
|
|
|
|
|
517
|
my $exists = exists $input->{$fname}; |
|
430
|
454
|
100
|
100
|
|
|
1237
|
next if ( $self->skip_fields_without_input && ! $exists && ! $field->has_input_without_param ); |
|
|
|
|
100
|
|
|
|
|
|
431
|
447
|
100
|
100
|
|
|
1288
|
if ( ! $exists && $field->disabled && ! $field->has_value ) { |
|
|
|
|
100
|
|
|
|
|
|
432
|
1
|
|
|
|
|
3
|
$field->fill_from_fields; |
|
433
|
|
|
|
|
|
|
} |
|
434
|
|
|
|
|
|
|
else { |
|
435
|
446
|
|
|
|
|
1703
|
$field->fill_from_params($input->{$fname}, $exists ); |
|
436
|
|
|
|
|
|
|
} |
|
437
|
447
|
100
|
|
|
|
1597
|
$my_input->{$fname} = $field->input if $field->has_input; |
|
438
|
|
|
|
|
|
|
} |
|
439
|
|
|
|
|
|
|
} |
|
440
|
|
|
|
|
|
|
# save input for this form or compound field. Used to determine whether really 'submitted' |
|
441
|
|
|
|
|
|
|
# in form. This should not be used for errors or fif or anything like that. |
|
442
|
160
|
100
|
|
|
|
671
|
$self->input( scalar keys %$my_input ? $my_input : {}); |
|
443
|
160
|
|
|
|
|
299
|
return; |
|
444
|
|
|
|
|
|
|
} |
|
445
|
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
sub fill_from_object { |
|
447
|
95
|
|
|
95
|
0
|
284
|
my ( $self, $obj ) = @_; |
|
448
|
|
|
|
|
|
|
|
|
449
|
95
|
50
|
33
|
|
|
207
|
return unless ( $obj || $self->has_fields ); # empty fields for compounds |
|
450
|
95
|
|
|
|
|
202
|
$self->filled_from('object'); |
|
451
|
95
|
|
|
|
|
78
|
my $my_value; |
|
452
|
|
|
|
|
|
|
my $init_obj; |
|
453
|
95
|
100
|
66
|
|
|
737
|
if ( $self->form && |
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
454
|
|
|
|
|
|
|
$self->form->fill_from_object_source && |
|
455
|
|
|
|
|
|
|
$self->form->fill_from_object_source eq 'model' && |
|
456
|
|
|
|
|
|
|
$self->form->has_init_values ) { |
|
457
|
6
|
|
|
|
|
30
|
$init_obj = $self->form->init_values; |
|
458
|
|
|
|
|
|
|
} |
|
459
|
95
|
|
|
|
|
1192
|
for my $field ( $self->all_sorted_fields ) { |
|
460
|
257
|
50
|
|
|
|
538
|
next if ! $field->is_active; |
|
461
|
257
|
100
|
100
|
|
|
4044
|
if ( (ref $obj eq 'HASH' && !exists $obj->{ $field->accessor } ) || |
|
|
|
|
100
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
462
|
|
|
|
|
|
|
( blessed($obj) && !$obj->can($field->accessor) ) ) { |
|
463
|
35
|
|
|
|
|
102
|
my $found = 0; |
|
464
|
|
|
|
|
|
|
|
|
465
|
35
|
100
|
|
|
|
51
|
if ($init_obj) { |
|
466
|
|
|
|
|
|
|
# if we're using a model, look for accessor not found in obj |
|
467
|
|
|
|
|
|
|
# in the init_values |
|
468
|
9
|
|
|
|
|
24
|
my @names = split( /\./, $field->full_name ); |
|
469
|
9
|
|
|
|
|
22
|
my $init_obj_value = $self->find_sub_obj( $init_obj, \@names ); |
|
470
|
9
|
100
|
|
|
|
24
|
if ( defined $init_obj_value ) { |
|
471
|
7
|
|
|
|
|
7
|
$found = 1; |
|
472
|
7
|
|
|
|
|
46
|
$field->fill_from_object( $init_obj_value ); |
|
473
|
|
|
|
|
|
|
} |
|
474
|
|
|
|
|
|
|
} |
|
475
|
|
|
|
|
|
|
|
|
476
|
35
|
100
|
|
|
|
102
|
$field->fill_from_fields() unless $found; |
|
477
|
|
|
|
|
|
|
} |
|
478
|
|
|
|
|
|
|
else { |
|
479
|
222
|
50
|
|
|
|
1295
|
my $value = $self->_get_value( $field, $obj ) unless $field->writeonly; |
|
480
|
222
|
|
|
|
|
670
|
$field->fill_from_object( $value ); |
|
481
|
|
|
|
|
|
|
} |
|
482
|
|
|
|
|
|
|
# TODO: the following doesn't work for 'input_without_param' fields like checkboxes |
|
483
|
|
|
|
|
|
|
# $my_value->{ $field->name } = $field->value if $field->has_value; |
|
484
|
257
|
|
|
|
|
939
|
$my_value->{ $field->name } = $field->value; |
|
485
|
|
|
|
|
|
|
} |
|
486
|
95
|
|
|
|
|
734
|
$self->value($my_value); |
|
487
|
95
|
|
|
|
|
288
|
return; |
|
488
|
|
|
|
|
|
|
} |
|
489
|
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
# for when there are no params and no init_values |
|
491
|
|
|
|
|
|
|
sub fill_from_fields { |
|
492
|
236
|
|
|
236
|
0
|
315
|
my ( $self ) = @_; |
|
493
|
|
|
|
|
|
|
|
|
494
|
236
|
|
|
|
|
819
|
$self->filled_from('fields'); |
|
495
|
|
|
|
|
|
|
# defaults for compounds, etc. |
|
496
|
236
|
100
|
|
|
|
895
|
if ( my @values = $self->get_default_value ) { |
|
497
|
6
|
50
|
|
|
|
753
|
my $value = @values > 1 ? \@values : shift @values; |
|
498
|
6
|
50
|
66
|
|
|
21
|
if( ref $value eq 'HASH' || blessed $value ) { |
|
499
|
6
|
|
|
|
|
118
|
return $self->fill_from_object( $value ); |
|
500
|
|
|
|
|
|
|
} |
|
501
|
0
|
0
|
|
|
|
0
|
if ( defined $value ) { |
|
502
|
0
|
|
|
|
|
0
|
$self->init_value($value); |
|
503
|
0
|
|
|
|
|
0
|
$self->value($value); |
|
504
|
|
|
|
|
|
|
} |
|
505
|
|
|
|
|
|
|
} |
|
506
|
230
|
|
|
|
|
254
|
my $my_value; |
|
507
|
230
|
|
|
|
|
794
|
for my $field ( $self->all_sorted_fields ) { |
|
508
|
632
|
50
|
|
|
|
1025
|
next if (!$field->is_active); |
|
509
|
632
|
|
|
|
|
2460
|
$field->fill_from_fields(); |
|
510
|
632
|
100
|
|
|
|
2602
|
$my_value->{ $field->name } = $field->value if $field->has_value; |
|
511
|
|
|
|
|
|
|
} |
|
512
|
|
|
|
|
|
|
# setting value here to handle disabled compound fields, where we want to |
|
513
|
|
|
|
|
|
|
# preserve the 'value' because the fields aren't submitted...except for the |
|
514
|
|
|
|
|
|
|
# form. Not sure it's the best idea to skip for form, but it maintains previous behavior |
|
515
|
230
|
100
|
|
|
|
745
|
$self->value($my_value) if ( keys %$my_value ); |
|
516
|
230
|
|
|
|
|
2517
|
return; |
|
517
|
|
|
|
|
|
|
} |
|
518
|
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
sub find_sub_obj { |
|
520
|
10
|
|
|
10
|
0
|
31
|
my ( $self, $obj, $field_name_array ) = @_; |
|
521
|
10
|
|
|
|
|
15
|
my $this_fname = shift @$field_name_array;; |
|
522
|
10
|
|
|
|
|
24
|
my $field = $self->field($this_fname); |
|
523
|
10
|
|
|
|
|
48
|
my $new_obj = $self->_get_value( $field, $obj ); |
|
524
|
10
|
50
|
|
|
|
21
|
if ( scalar @$field_name_array ) { |
|
525
|
0
|
|
|
|
|
0
|
$new_obj = $field->find_sub_obj( $new_obj, $field_name_array ); |
|
526
|
|
|
|
|
|
|
} |
|
527
|
10
|
|
|
|
|
18
|
return $new_obj; |
|
528
|
|
|
|
|
|
|
} |
|
529
|
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
sub _get_value { |
|
533
|
232
|
|
|
232
|
|
230
|
my ( $self, $field, $obj ) = @_; |
|
534
|
|
|
|
|
|
|
|
|
535
|
232
|
|
|
|
|
3134
|
my $accessor = $field->accessor; |
|
536
|
232
|
|
|
|
|
905
|
my @values; |
|
537
|
232
|
100
|
66
|
|
|
783
|
if ( blessed($obj) && $obj->can($accessor) ) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
# this must be an array, so that DBIx::Class relations are arrays not resultsets |
|
539
|
11
|
|
|
|
|
27
|
@values = $obj->$accessor; |
|
540
|
|
|
|
|
|
|
# for non-DBIC blessed object where access returns arrayref |
|
541
|
11
|
100
|
66
|
|
|
59
|
if ( scalar @values == 1 && ref $values[0] eq 'ARRAY' && $field->multiple ) { |
|
|
|
|
66
|
|
|
|
|
|
542
|
1
|
|
|
|
|
1
|
@values = @{$values[0]}; |
|
|
1
|
|
|
|
|
2
|
|
|
543
|
|
|
|
|
|
|
} |
|
544
|
|
|
|
|
|
|
} |
|
545
|
|
|
|
|
|
|
elsif ( exists $obj->{$accessor} ) { |
|
546
|
216
|
|
|
|
|
222
|
my $v = $obj->{$accessor}; |
|
547
|
216
|
100
|
100
|
|
|
522
|
if($field->multiple && ref($v) eq 'ARRAY'){ |
|
548
|
2
|
|
|
|
|
7
|
@values = @$v; |
|
549
|
|
|
|
|
|
|
} else { |
|
550
|
214
|
|
|
|
|
318
|
@values = $v; |
|
551
|
|
|
|
|
|
|
} |
|
552
|
|
|
|
|
|
|
} |
|
553
|
|
|
|
|
|
|
elsif ( @values = $field->get_default_value ) { |
|
554
|
|
|
|
|
|
|
} |
|
555
|
|
|
|
|
|
|
else { |
|
556
|
2
|
|
|
|
|
3
|
return; |
|
557
|
|
|
|
|
|
|
} |
|
558
|
230
|
100
|
|
|
|
535
|
if( $field->has_transform_default_to_value ) { |
|
559
|
8
|
|
|
|
|
28
|
@values = $field->transform_default_to_value->($field, @values); |
|
560
|
|
|
|
|
|
|
} |
|
561
|
230
|
|
|
|
|
206
|
my $value; |
|
562
|
230
|
100
|
|
|
|
344
|
if( $field->multiple ) { |
|
563
|
5
|
100
|
100
|
|
|
40
|
if ( scalar @values == 1 && ! defined $values[0] ) { |
|
|
|
100
|
100
|
|
|
|
|
|
564
|
1
|
|
|
|
|
2
|
$value = []; |
|
565
|
|
|
|
|
|
|
} |
|
566
|
|
|
|
|
|
|
elsif ( scalar @values == 1 && ref $values[0] eq 'ARRAY' ) { |
|
567
|
1
|
|
|
|
|
7
|
$value = shift @values; |
|
568
|
|
|
|
|
|
|
} |
|
569
|
|
|
|
|
|
|
else { |
|
570
|
3
|
|
|
|
|
6
|
$value = \@values; |
|
571
|
|
|
|
|
|
|
} |
|
572
|
|
|
|
|
|
|
} |
|
573
|
|
|
|
|
|
|
else { |
|
574
|
225
|
50
|
|
|
|
365
|
$value = @values > 1 ? \@values : shift @values; |
|
575
|
|
|
|
|
|
|
} |
|
576
|
230
|
|
|
|
|
310
|
return $value; |
|
577
|
|
|
|
|
|
|
} |
|
578
|
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
sub fields_set_value { |
|
581
|
103
|
|
|
103
|
0
|
121
|
my $self = shift; |
|
582
|
103
|
|
|
|
|
121
|
my %value_hash; |
|
583
|
103
|
|
|
|
|
261
|
foreach my $field ( $self->all_fields ) { |
|
584
|
305
|
100
|
|
|
|
1389
|
next if ! $field->is_active; |
|
585
|
302
|
100
|
100
|
|
|
4887
|
$value_hash{ $field->accessor } = $field->value |
|
586
|
|
|
|
|
|
|
if ( $field->has_value && !$field->no_update ); |
|
587
|
|
|
|
|
|
|
} |
|
588
|
103
|
|
|
|
|
944
|
$self->value( \%value_hash ); |
|
589
|
|
|
|
|
|
|
} |
|
590
|
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
sub clear_data { |
|
593
|
133
|
|
|
133
|
0
|
401
|
my $self = shift; |
|
594
|
133
|
|
|
|
|
432
|
$self->clear_input; |
|
595
|
133
|
|
|
|
|
11546
|
$self->clear_value; |
|
596
|
|
|
|
|
|
|
# TODO - better way? |
|
597
|
133
|
100
|
|
|
|
489
|
$self->_clear_active unless $self->is_form;; |
|
598
|
133
|
|
|
|
|
1313
|
$self->clear_error_fields; |
|
599
|
133
|
|
|
|
|
346
|
$self->clear_filled_from; |
|
600
|
133
|
|
|
|
|
2306
|
foreach my $field ( $self->all_fields ) { |
|
601
|
349
|
|
|
|
|
12884
|
$field->clear_data; |
|
602
|
|
|
|
|
|
|
} |
|
603
|
|
|
|
|
|
|
} |
|
604
|
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
# References to fields with errors are propagated up the tree. |
|
606
|
|
|
|
|
|
|
# All fields with errors should end up being in the form's |
|
607
|
|
|
|
|
|
|
# error_results. Once. |
|
608
|
|
|
|
|
|
|
sub propagate_error { |
|
609
|
81
|
|
|
81
|
0
|
563
|
my ( $self, $field ) = @_; |
|
610
|
|
|
|
|
|
|
|
|
611
|
81
|
|
|
|
|
271
|
$self->add_error_field($field); |
|
612
|
81
|
100
|
|
|
|
8818
|
if ( $self->parent ) { |
|
613
|
16
|
|
|
|
|
260
|
$self->parent->propagate_error( $field ); |
|
614
|
|
|
|
|
|
|
} |
|
615
|
|
|
|
|
|
|
} |
|
616
|
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
1; |
|
618
|
|
|
|
|
|
|
|
|
619
|
|
|
|
|
|
|
__END__ |
|
620
|
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
=pod |
|
622
|
|
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
=encoding UTF-8 |
|
624
|
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
=head1 NAME |
|
626
|
|
|
|
|
|
|
|
|
627
|
|
|
|
|
|
|
Data::MuForm::Fields - Common attributes and methods for forms and compound fields |
|
628
|
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
=head1 VERSION |
|
630
|
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
version 0.03 |
|
632
|
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
=head2 NAME |
|
634
|
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
Data::MuForm::Fields |
|
636
|
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
=head2 DESCRIPTION |
|
638
|
|
|
|
|
|
|
|
|
639
|
|
|
|
|
|
|
This role holds things that are common to Data::MuForm and compound fields. |
|
640
|
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
Includes code that was split up into multiple roles in FormHandler: Fields, |
|
642
|
|
|
|
|
|
|
BuildFields, InitResult. |
|
643
|
|
|
|
|
|
|
|
|
644
|
|
|
|
|
|
|
=head1 AUTHOR |
|
645
|
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
Gerda Shank |
|
647
|
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
|
649
|
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
This software is copyright (c) 2017 by Gerda Shank. |
|
651
|
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
|
653
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
|
654
|
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
=cut |