File Coverage

blib/lib/HTML/FormFu/ObjectUtil.pm
Criterion Covered Total %
statement 124 133 93.2
branch 36 48 75.0
condition 8 12 66.6
subroutine 21 24 87.5
pod 0 10 0.0
total 189 227 83.2


line stmt bran cond sub pod time code
1 405     405   3375 use strict;
  405         903  
  405         21359  
2              
3             package HTML::FormFu::ObjectUtil;
4             # ABSTRACT: utilities for dealing with FormFu objects
5             $HTML::FormFu::ObjectUtil::VERSION = '2.07';
6 405     405   2371 use warnings;
  405         796  
  405         14107  
7              
8 405     405   2186 use Exporter qw( import );
  405         840  
  405         14462  
9              
10 405         27573 use HTML::FormFu::Util qw(
11             _parse_args require_class
12             _get_elements
13             _filter_components _merge_hashes
14 405     405   2418 );
  405         906  
15 405     405   173138 use Clone ();
  405         1013390  
  405         10724  
16 405     405   186390 use Config::Any;
  405         3355534  
  405         16209  
17 405     405   206041 use Data::Visitor::Callback;
  405         35748547  
  405         17260  
18 405     405   3878 use File::Spec;
  405         927  
  405         13411  
19 405     405   2388 use Scalar::Util qw( refaddr weaken blessed );
  405         948  
  405         28013  
20 405     405   2664 use Carp qw( croak );
  405         998  
  405         546100  
21              
22             our @EXPORT_OK = ( qw(
23             deflator
24             load_config_file load_config_filestem
25             form
26             get_parent
27             insert_before insert_after
28             clone
29             name
30             stash
31             parent
32             nested_name nested_names
33             remove_element
34             _string_equals _object_equals
35             _load_file
36             ),
37             );
38              
39             sub load_config_file {
40 145     145 0 1426 my ( $self, @files ) = @_;
41              
42 145         396 my $use_stems = 0;
43              
44 145         748 return _load_config( $self, $use_stems, @files );
45             }
46              
47             sub load_config_filestem {
48 1     1 0 11 my ( $self, @files ) = @_;
49              
50 1         4 my $use_stems = 1;
51              
52 1         6 return _load_config( $self, $use_stems, @files );
53             }
54              
55             sub _load_config {
56 146     146   540 my ( $self, $use_stems, @filenames ) = @_;
57              
58 146 100 66     1464 if ( scalar @filenames == 1 && ref $filenames[0] eq 'ARRAY' ) {
59 1         3 @filenames = @{ $filenames[0] };
  1         4  
60             }
61              
62 146         771 my $config_callback = $self->config_callback;
63 146         323 my $data_visitor;
64              
65 146 100       508 if ( defined $config_callback ) {
66 2         77 $data_visitor = Data::Visitor::Callback->new( %$config_callback,
67             ignore_return_values => 1, );
68             }
69              
70 146 100       1162 my $config_any_arg = $use_stems ? 'stems' : 'files';
71 146 100       493 my $config_any_method = $use_stems ? 'load_stems' : 'load_files';
72              
73 146         326 my @config_file_path;
74              
75 146 100       632 if ( my $config_file_path = $self->config_file_path ) {
76              
77 4 100       12 if ( ref $config_file_path eq 'ARRAY' ) {
78 3         10 push @config_file_path, @$config_file_path;
79             }
80             else {
81 1         3 push @config_file_path, $config_file_path;
82             }
83             }
84             else {
85 142         2100 push @config_file_path, File::Spec->curdir;
86             }
87              
88 146         510 for my $file (@filenames) {
89 147         397 my $loaded = 0;
90 147         303 my $fullpath;
91              
92 147         404 foreach my $config_file_path (@config_file_path) {
93              
94 154 50 33     1667 if ( defined $config_file_path
95             && !File::Spec->file_name_is_absolute($file) )
96             {
97 154         2336 $fullpath = File::Spec->catfile( $config_file_path, $file );
98             }
99             else {
100 0         0 $fullpath = $file;
101             }
102              
103 154         2529 my $config = Config::Any->$config_any_method(
104             { $config_any_arg => [$fullpath],
105             use_ext => 1,
106             driver_args => { General => { -UTF8 => 1 }, },
107             } );
108              
109 154 100       1938842 next if !@$config;
110              
111 146         983 $loaded = 1;
112 146         8687 my ( $filename, $filedata ) = %{ $config->[0] };
  146         1012  
113              
114 146         880 _load_file( $self, $data_visitor, $filedata );
115 146         2774 last;
116             }
117 147 100       1035 croak "config file '$file' not found" if !$loaded;
118             }
119              
120 145         1379 return $self;
121             }
122              
123             sub _load_file {
124 146     146   1385 my ( $self, $data_visitor, $data ) = @_;
125              
126 146 100       5200 if ( defined $data_visitor ) {
127 2         13 $data_visitor->visit($data);
128             }
129              
130 146 100       8488 for my $config ( ref $data eq 'ARRAY' ? @$data : $data ) {
131 147         5349 $self->populate( Clone::clone($config) );
132             }
133              
134 146         1019 return;
135             }
136              
137             sub form {
138 29320     29320 0 49466 my ($self) = @_;
139              
140             # micro optimization! this method's called a lot, so access
141             # parent hashkey directly, instead of calling parent()
142 29320         67250 while ( defined( my $parent = $self->{parent} ) ) {
143 50489         104411 $self = $parent;
144             }
145              
146 29320         659192 return $self;
147             }
148              
149             sub clone {
150 2     2 0 663 my ($self) = @_;
151              
152 2         33 my %new = %$self;
153              
154 2         7 $new{_elements} = [ map { $_->clone } @{ $self->_elements } ];
  2         36  
  2         117  
155 2         12 $new{attributes} = Clone::clone( $self->attributes );
156 2         13 $new{tt_args} = Clone::clone( $self->tt_args );
157 2         11 $new{model_config} = Clone::clone( $self->model_config );
158              
159 2 50       14 if ( $self->can('_plugins') ) {
160 2         5 $new{_plugins} = [ map { $_->clone } @{ $self->_plugins } ];
  0         0  
  2         62  
161             }
162              
163             $new{languages}
164 2 50       92 = ref $self->languages
165             ? Clone::clone( $self->languages )
166             : $self->languages;
167              
168 2         11 $new{default_args} = $self->default_args;
169              
170 2         11 my $obj = bless \%new, ref $self;
171              
172 2         7 map { $_->parent($obj) } @{ $new{_elements} };
  2         24  
  2         17  
173              
174 2         8 return $obj;
175             }
176              
177             sub name {
178 111     111 0 3279 my $self = shift;
179              
180 111 50       248 croak 'cannot use name() as a setter' if @_;
181              
182 111         222 return $self->parent->name;
183             }
184              
185             sub nested_name {
186 1119     1119 0 2193 my $self = shift;
187              
188 1119 50       2840 croak 'cannot use nested_name() as a setter' if @_;
189              
190 1119         2746 return $self->parent->nested_name;
191             }
192              
193             sub nested_names {
194 0     0 0 0 my $self = shift;
195              
196 0 0       0 croak 'cannot use nested_names() as a setter' if @_;
197              
198 0         0 return $self->parent->nested_names;
199             }
200              
201             sub stash {
202 5141     5141 0 9796 my $self = shift;
203              
204 5141 100       14801 $self->{stash} = {} if not exists $self->{stash};
205 5141 100       16370 return $self->{stash} if !@_;
206              
207 3311 50       9439 my %attrs = ( @_ == 1 ) ? %{ $_[0] } : @_;
  3311         7941  
208              
209 3311         8335 $self->{stash}->{$_} = $attrs{$_} for keys %attrs;
210              
211 3311         7102 return $self;
212             }
213              
214             sub parent {
215 16459     16459 0 29033 my $self = shift;
216              
217 16459 100       33540 if (@_) {
218 2468         5645 $self->{parent} = shift;
219              
220 2468         10837 weaken( $self->{parent} );
221              
222 2468         6637 return $self;
223             }
224              
225 13991         75072 return $self->{parent};
226             }
227              
228             sub get_parent {
229 70     70 0 125 my $self = shift;
230              
231 70 100       157 return $self->parent
232             if !@_;
233              
234 69         183 my %args = _parse_args(@_);
235              
236 69         178 while ( defined( my $parent = $self->parent ) ) {
237              
238 140         303 for my $name ( keys %args ) {
239 140         188 my $value;
240              
241 140 100 66     4005 if ( $parent->can($name)
      100        
242             && defined( $value = $parent->$name )
243             && $value eq $args{$name} )
244             {
245 67         306 return $parent;
246             }
247             }
248              
249 73         195 $self = $parent;
250             }
251              
252 2         11 return;
253             }
254              
255             sub _string_equals {
256 0     0     my ( $a, $b ) = @_;
257              
258 0 0         return blessed($b)
259             ? ( refaddr($a) eq refaddr($b) )
260             : ( "$a" eq "$b" );
261             }
262              
263             sub _object_equals {
264 0     0     my ( $a, $b ) = @_;
265              
266 0 0         return blessed($b)
267             ? ( refaddr($a) eq refaddr($b) )
268             : undef;
269             }
270              
271             1;
272              
273             __END__
274              
275             =pod
276              
277             =encoding UTF-8
278              
279             =head1 NAME
280              
281             HTML::FormFu::ObjectUtil - utilities for dealing with FormFu objects
282              
283             =head1 VERSION
284              
285             version 2.07
286              
287             =head1 AUTHOR
288              
289             Carl Franks <cpan@fireartist.com>
290              
291             =head1 COPYRIGHT AND LICENSE
292              
293             This software is copyright (c) 2018 by Carl Franks.
294              
295             This is free software; you can redistribute it and/or modify it under
296             the same terms as the Perl 5 programming language system itself.
297              
298             =cut