File Coverage

blib/lib/RapidApp/TableSpec/Column.pm
Criterion Covered Total %
statement 83 107 77.5
branch 19 42 45.2
condition 5 15 33.3
subroutine 13 17 76.4
pod 0 9 0.0
total 120 190 63.1


line stmt bran cond sub pod time code
1             package RapidApp::TableSpec::Column;
2              
3 5     5   34 use strict;
  5         11  
  5         131  
4 5     5   21 use warnings;
  5         9  
  5         109  
5 5     5   20 use Try::Tiny;
  5         11  
  5         328  
6              
7             # This class must declare the version because we declared it before (and PAUSE knows)
8             our $VERSION = '0.99301';
9              
10 5     5   38 use Moose;
  5         18  
  5         33  
11              
12 5     5   27192 use RapidApp::Util qw(:all);
  5         10  
  5         1879  
13              
14 5     5   2128 use RapidApp::TableSpec::Column::Profile qw( get_set );
  5         13  
  5         5987  
15              
16              
17             around BUILDARGS => sub {
18             my $orig = shift;
19             my $class = shift;
20             my %params = (ref($_[0]) eq 'HASH') ? %{ $_[0] } : @_; # <-- arg as hash or hashref
21            
22             # These options were never published/used and are being removed to
23             # be able to implement a new design with better performance. But,
24             # just in case they are out in the wild, catch and throw and error:
25             my @bad_opts = qw(profile_definitions base_profiles);
26             exists $params{$_} and die "Param '$_' no longer supported" for (@bad_opts);
27            
28             #my $profile_defs = $class->_build_profile_definitions;
29             #$profile_defs = merge($profile_defs, delete $params{profile_definitions}) if ($params{profile_definitions});
30            
31             $params{properties_underlay} = {} unless ($params{properties_underlay});
32             $params{profiles} = [ $params{profiles} ] if ($params{profiles} and not ref($params{profiles}));
33            
34             #my @base_profiles = ( $class->DEFAULT_BASE_PROFILES );
35             #push @base_profiles, @{ delete $params{base_profiles} } if($params{base_profiles});
36             #my @profiles = @base_profiles;
37             #push @profiles,
38            
39             my @profiles = $params{profiles} ? @{ delete $params{profiles} } : ();
40            
41             # Apply/merge profiles if defined:
42             $class->collapse_apply_profiles($params{properties_underlay},@profiles);
43            
44             #$params{profile_definitions} = $profile_defs;
45             #$params{base_profiles} = \@base_profiles;
46             return $class->$orig(%params);
47             };
48              
49              
50             sub collapse_apply_profiles {
51 2188     2188 0 3304 my $self = shift;
52 2188 50       4221 my $target = shift or die "collapse_apply_profiles(): missing arguments";
53 2188         4213 my @base_profiles = @_;
54              
55 2188         3511 my $profiles = [];
56 2188 50       4261 $profiles = delete $target->{profiles} if($target->{profiles});
57 2188 50       4374 $profiles = [ $profiles ] unless (ref $profiles);
58 2188         5000 @$profiles = (@base_profiles,@$profiles);
59              
60 2188 50       4285 return unless (scalar @$profiles > 0);
61              
62 2188         2959 my %prof = ();
63 2188         3510 @$profiles = grep { ! $prof{$_}++ } @$profiles;
  7648         16863  
64              
65 2188         6025 my $collapsed = get_set(@$profiles);
66              
67             # -- Github issue #61
68             # This is special handling for 'bool' - we need to add the 3rd, '(not set)' option
69             # if it is nullable. We have to do this here because the profile definitions are
70             # currently passive and cannot natively change themselves based on the existence
71             # of other profiles. This is something we want to generalize in the future, when
72             # we will probably turn profiles into real class objects
73 2188 50 66     4696 if($prof{bool} && $prof{nullable} && ! $prof{notnull}) {
      33        
74 0     0   0 my $selections = try{$collapsed->{menu_select_editor}{selections}};
  0         0  
75 0 0 0     0 unshift @$selections, {
      0        
76             #iconCls => "ra-icon-cross-light-12x12",
77             text => '(not set)',
78             value => undef
79             } if ($selections && ref($selections) eq 'ARRAY' && scalar(@$selections) == 2);
80             }
81             # --
82              
83 2188         2757 %$target = %{ merge($target,$collapsed) };
  2188         5818  
84             }
85              
86              
87              
88              
89             has 'name' => ( is => 'ro', isa => 'Str', required => 1 );
90             #has 'order' => ( is => 'rw', isa => 'Maybe[Int]', default => undef, clearer => 'clear_order' );
91             has 'permission_roles' => ( is => 'rw', isa => 'Maybe[HashRef[ArrayRef]]', default => undef );
92             has '_other_properties' => ( is => 'ro', isa => 'HashRef', default => sub {{}} );
93              
94             #has 'base_profiles' => ( is => 'ro', isa => 'ArrayRef', default => sub {[]} );
95             #
96             #has 'profile_definitions' => ( is => 'ro', isa => 'HashRef', lazy_build => 1 );
97             #sub _build_profile_definitions {
98             # my $self = shift;
99             # my $defs = $self->DEFAULT_PROFILES();
100             #
101             # # TODO collapse sub-profile defs
102             # return $defs;
103             #}
104              
105              
106             # properties that get merged under actual properties - collapsed from profiles:
107             has 'properties_underlay' => ( is => 'ro', isa => 'HashRef', default => sub {{}} );
108             sub apply_profiles {
109 1094     1094 0 1702 my $self = shift;
110 1094         1969 my @profiles = @_;
111 1094 50       2373 @profiles = @{$_[0]} if (ref $_[0]);
  1094         2213  
112            
113 1094 50       2653 return unless (scalar @profiles > 0);
114            
115 1094         30216 $self->collapse_apply_profiles(
116             $self->properties_underlay,
117             @profiles
118             );
119             }
120              
121             has 'exclude_attr_property_names' => (
122             is => 'ro', isa => 'HashRef',
123             default => sub {
124             my @list = (
125             'exclude_property_names',
126             'properties_underlay',
127             '_other_properties',
128             'extra_properties'
129             );
130             return { map {$_ => 1} @list };
131             });
132              
133              
134             sub get_property {
135 0     0 0 0 my $self = shift;
136 0         0 my $name = shift;
137            
138 0         0 my $attr = $self->meta->get_attribute($name);
139 0 0       0 return $attr->get_value($self) if ($attr);
140            
141 0         0 return $self->_other_properties->{$name};
142             }
143              
144             sub set_properties {
145 1386     1386 0 2257 my $self = shift;
146 1386 100       3484 my %new = (ref($_[0]) eq 'HASH') ? %{ $_[0] } : @_; # <-- arg as hash or hashref
  1094         5172  
147            
148 1386 100       6213 $self->apply_profiles(delete $new{profiles}) if ($new{profiles});
149            
150 1386         5469 foreach my $key (keys %new) {
151 8339         19032 my $attr = $self->meta->get_attribute($key);
152 8339 50 66     181837 if ($attr and $attr->has_write_method) {
153 0         0 $self->$key($new{$key});
154             }
155             else {
156 8339         220880 $self->_other_properties->{$key} = $new{$key};
157             }
158             }
159             }
160              
161             # Only sets properties not already defined:
162             sub set_properties_If {
163 0     0 0 0 my $self = shift;
164 0 0       0 my %new = (ref($_[0]) eq 'HASH') ? %{ $_[0] } : @_; # <-- arg as hash or hashref
  0         0  
165            
166 0         0 foreach my $prop (keys %new) {
167 0 0       0 $self->get_property($prop) and delete $new{$prop};
168             }
169            
170 0         0 return $self->set_properties(%new);
171             }
172              
173             has 'extra_properties', is => 'ro', isa => 'HashRef', default => sub {{}};
174             sub all_properties_hash {
175 1073     1073 0 1513 my $self = shift;
176            
177 1073         1304 my %hash = %{ $self->_other_properties };
  1073         28283  
178            
179 1073         4070 foreach my $attr ($self->meta->get_all_attributes) {
180 7511 100       552533 next if ($self->exclude_attr_property_names->{$attr->name});
181 4292 50       10187 next unless ($attr->has_value($self));
182 4292         142351 $hash{$attr->name} = $attr->get_value($self);
183             }
184            
185 1073         108283 my $props = { %{$self->properties_underlay},%hash };
  1073         27827  
186            
187             # added 'extra_properties' for extra properties that can be merged (past the first
188             # level), specifically, for 'editor'. Notice above that the merge with 'properties_underlay'
189             # is one-layer. This has gotten complicated and ugly and needs refactoring...
190 1073         27517 return merge($self->extra_properties,$props);
191             }
192              
193             # Returns a hashref of properties that match the list/hash supplied:
194             sub properties_limited {
195 781     781 0 1226 my $self = shift;
196 781         933 my $map;
197            
198 781 50       2371 if (ref($_[0]) eq 'HASH') { $map = shift; }
  0 50       0  
199 781         964 elsif (ref($_[0]) eq 'ARRAY') { $map = { map { $_ => 1 } @{$_[0]} }; }
  40612         59739  
  781         1570  
200 0         0 else { $map = { map { $_ => 1 } @_ }; }
  0         0  
201            
202 781         3483 my $properties = $self->all_properties_hash;
203            
204 781         3027 my @keys = grep { $map->{$_} } keys %$properties;
  13836         17299  
205            
206 781         1658 my $set = {};
207 781         1417 foreach my $key (@keys) {
208 9010         13436 $set->{$key} = $properties->{$key};
209             }
210            
211 781         6987 return $set;
212             }
213              
214              
215             sub copy {
216 292     292 0 508 my $self = shift;
217 292 50       991 my %opts = (ref($_[0]) eq 'HASH') ? %{ $_[0] } : @_; # <-- arg as hash or hashref
  0         0  
218            
219 292         451 my %attr = ();
220 292         432 my %other = ();
221            
222 292         614 foreach my $opt (keys %opts) {
223 272 50       828 if ($self->meta->find_attribute_by_name($opt)) {
224 0         0 $attr{$opt} = $opts{$opt};
225             }
226             else {
227 272         22041 $other{$opt} = $opts{$opt};
228             }
229             }
230            
231 292         892 my $Copy = $self->meta->clone_object(Clone::clone($self),%attr);
232             #$self,
233             #%attr,
234             # This shouldn't be required, but is. The clone doesn't clone _other_properties!
235             #_other_properties => { %{ $self->_other_properties } }
236             #);
237            
238 292         151804 $Copy->set_properties(%other);
239              
240 292         3864 return $Copy;
241             }
242              
243              
244             has 'rapidapp_init_coderef' => ( is => 'rw', isa => 'Maybe[CodeRef]', default => undef );
245             sub call_rapidapp_init_coderef {
246 0     0 0   my $self = shift;
247 0 0         return unless ($self->rapidapp_init_coderef);
248            
249             ### Call ###
250 0           $self->rapidapp_init_coderef->($self,@_);
251             ############
252              
253             # Clear:
254 0           $self->rapidapp_init_coderef(undef);
255             }
256              
257              
258 5     5   38 no Moose;
  5         23  
  5         37  
259             __PACKAGE__->meta->make_immutable;
260             1;