File Coverage

blib/lib/OpusVL/Preferences/RolesFor/ResultSet/PrfOwner.pm
Criterion Covered Total %
statement 12 128 9.3
branch 0 38 0.0
condition 0 3 0.0
subroutine 4 17 23.5
pod 12 12 100.0
total 28 198 14.1


line stmt bran cond sub pod time code
1              
2             package OpusVL::Preferences::RolesFor::ResultSet::PrfOwner;
3              
4 1     1   2885 use strict;
  1         2  
  1         26  
5 1     1   4 use warnings;
  1         2  
  1         22  
6 1     1   4 use Moose::Role;
  1         2  
  1         5  
7 1     1   4184 use Carp;
  1         3  
  1         1116  
8              
9             sub prf_get_default
10             {
11 0     0 1   my $self = shift;
12 0           my $name = shift;
13              
14 0           my $defaults = $self->prf_defaults;
15              
16             return
17 0 0         unless defined $defaults;
18              
19 0           my $def = $defaults->find ({ name => $name });
20              
21             return
22 0 0         unless defined $def;
23              
24 0           return $def->default_value;
25             }
26              
27             sub prf_set_default
28             {
29 0     0 1   my $self = shift;
30 0           my $name = shift;
31 0           my $value = shift;
32            
33 0           $self->setup_owner_type;
34 0           $self->prf_defaults->update_or_create
35             ({
36             name => $name,
37             default_value => $value
38             });
39             }
40              
41             sub setup_owner_type
42             {
43 0     0 1   my $self = shift;
44 0           my $schema = $self->result_source->schema;
45 0           my $source = $self->result_source;
46              
47 0           return $schema->resultset ('PrfOwnerType')->setup_from_source ($source);
48             }
49              
50             sub get_owner_type
51             {
52 0     0 1   my $self = shift;
53 0           my $schema = $self->result_source->schema;
54 0           my $source = $self->result_source;
55              
56 0           return $schema->resultset ('PrfOwnerType')->get_from_source ($source);
57             }
58              
59             sub prf_defaults
60             {
61 0     0 1   my $self = shift;
62 0           my $schema = $self->result_source->schema;
63 0           my $type = $self->setup_owner_type; # we always want a result here
64              
65 0           return $type->prf_defaults;
66             }
67              
68             sub prf_preferences
69             {
70 0     0 1   my $self = shift;
71 0           return $self->search_related('prf_owner')->search_related('prf_preferences');
72             }
73              
74             sub with_fields
75             {
76 0     0 1   my ($self, $args) = @_;
77              
78 0           my @params;
79             my @joins;
80 0           my $x = 1;
81             # well this sucks, we need to figure out if these are encrypted fields.
82             # we can't do this entirely at the DB layer.
83 0           my $schema = $self->result_source->schema;
84 0           my $crypto = $schema->encryption_client;
85 0 0         if($crypto)
86             {
87             # no point in checking for encryption unless we have a crypto object setup.
88 0           my $fields = $self->prf_defaults->search({
89             name => { -in => [keys %$args] },
90             encrypted => 1,
91             });
92 0           for my $f ($fields->all)
93             {
94             # encrypt the values.
95             # since this is a search do it deterministicly
96             # this won't find values for fields that weren't encrypted deterministicly
97             # but we can't find them anyway, so this will effectively fail closed.
98             # which is about as good as it gets.
99             # we could emit a warning when they try to search one of those fields though.
100 0 0 0       unless($f->unique_field || $f->searchable)
101             {
102 0           my $name = $f->name;
103 0           carp "Field $name is being searched for it's encrypted and does not have the searchable flag set so we will probably not find any results.";
104             }
105 0           $self->_encrypt_query_values($crypto, $args, $f->name);
106             }
107             }
108 0           for my $name (keys %$args)
109             {
110 0 0         my $alias = $x == 1 ? "prf_preferences" : "prf_preferences_$x";
111 0           my $value = $args->{$name};
112 0           push @params, {
113             "$alias.name" => $name,
114             "$alias.value" => $value,
115             };
116 0           push @joins, 'prf_preferences';
117 0           $x++;
118             }
119 0           return $self->search({ -and => \@params }, {
120             join => { prf_owner => \@joins }
121             });
122             }
123              
124             sub select_extra_fields
125             {
126 0     0 1   my ($self, @names) = @_;
127              
128 0           my @params;
129             my @joins;
130 0           my $x = 1;
131 0           my %aliases;
132 0           for my $name (@names)
133             {
134 0 0         my $alias = $x == 1 ? "_by_name" : "_by_name_$x";
135 0           push @params, $name;
136 0           push @joins, '_by_name';
137 0           $aliases{$name} = $alias;
138 0           $x++;
139             }
140 0           my $rs = $self->search(undef, {
141             bind => \@params,
142             join => { prf_owner => \@joins },
143             });
144 0           return { rs => $rs, aliases => \%aliases };
145             }
146              
147             sub prefetch_extra_fields
148             {
149 0     0 1   my ($self, @names) = @_;
150              
151 0           my @params;
152             my @joins;
153 0           my $x = 1;
154 0           my %aliases;
155             my @columns;
156 0           for my $name (@names)
157             {
158 0 0         my $alias = $x == 1 ? "_by_name" : "_by_name_$x";
159 0           push @params, $name;
160 0           push @columns, { "extra_$name" => "$alias.value" };
161 0           push @joins, '_by_name';
162 0           $aliases{$name} = $alias;
163 0           $x++;
164             }
165 0           my $rs = $self->search(undef, {
166             bind => \@params,
167             # Doing this manually since prefetch tries to be too clever
168             # by collapsing stuff and then providing no way to get to the dat
169             # as it doesn't consider multiple joins of the same relationship
170             # to be sane.
171             # Also our data should be flat (there should only be 1 or 0 row we're joining to
172             # so we don't need to do that collapse business.
173             join => { prf_owner => \@joins },
174             '+columns' => \@columns,
175             });
176 0           return { rs => $rs, aliases => \%aliases };
177             }
178              
179             sub join_by_name
180             {
181 0     0 1   my $self = shift;
182 0           my $name = shift;
183 0           $self->search(undef, {
184             join => [{ 'prf_owner' => '_by_name' }],
185             bind => [ $name ],
186             });
187             }
188              
189             sub validate_extra_parameter
190             {
191 0     0 1   my $self = shift;
192 0           my $field = shift;
193 0           my $params = shift;
194 0           my $unique_validator = shift;
195 0           my $id = shift;
196              
197 0 0         if($field->required)
198             {
199 0 0         return 'Must specify ' . $field->name unless exists $params->{$field->name};
200             }
201 0 0         if($field->unique_field)
202             {
203             # check to see if it's unique
204 0           my $p = {
205             prf_owner_type_id => $field->prf_owner_type_id,
206             };
207 0 0         $p->{id} = $id if $id;
208             my $error = $unique_validator->validate('global_fields_' . $field->name,
209 0           $params->{$field->name}, $p,
210             { label => $field->comment });
211 0 0         return $error if $error;
212             }
213             # FIXME: ought to check types.
214             }
215              
216             sub validate_extra_parameters
217             {
218 0     0 1   my $self = shift;
219 0           my $params = shift;
220 0           my $unique_validator = shift;
221 0           my $id = shift;
222              
223             # check them against their defaults.
224 0           my @fields = $self->prf_defaults->active;
225 0           for my $field (@fields)
226             {
227 0           my $error = $self->validate_extra_parameter($field, $params, $unique_validator, $id);
228 0 0         return $error if $error;
229             }
230             }
231              
232             sub _encrypt_query_values
233             {
234 0     0     my $self = shift;
235 0           my $crypto = shift;
236 0           my $hash = shift;
237 0           my $new_key = shift;
238 0           my $val = $hash->{$new_key};
239              
240 0 0         if(ref $val eq 'HASH')
241             {
242 0           my @ops = keys %$val;
243 0           for my $op (@ops)
244             {
245 0 0         if($op =~ /-?ident/)
246             {
247             # skip this.
248 0           return;
249             }
250 0 0         if(ref $val->{$op} eq 'ARRAY')
    0          
    0          
251             {
252             my @encrypted = map {
253 0           $crypto->encrypt_deterministic($_)
254 0           } @{$val->{$op}};
  0            
255 0           $val->{$op} = \@encrypted;
256             }
257             elsif(ref $val->{$op} eq 'HASHREF')
258             {
259             # I have no idea what to do with this.
260             # going to stop here.
261 0           carp 'Unrecognised search query, not encrypting possible reference to token number';
262             }
263             elsif(!ref $val->{$op})
264             {
265             # convert what we assume is a single value.
266 0           my $value = $val->{$op};
267 0 0         if($op =~ /like/i)
268             {
269             # NOTE:
270             # this could cause some fun and games.
271 0           $value =~ s/[%?]//g;
272             }
273 0           my $enc = $crypto->encrypt_deterministic($value);
274 0           $val->{$op} = $enc;
275             }
276             }
277             }
278             else
279             {
280 0           my $new_value = $crypto->encrypt_deterministic($val);
281 0           $hash->{$new_key} = $new_value;
282             }
283             }
284              
285              
286             return 1;
287              
288             __END__
289              
290             =pod
291              
292             =encoding UTF-8
293              
294             =head1 NAME
295              
296             OpusVL::Preferences::RolesFor::ResultSet::PrfOwner
297              
298             =head1 VERSION
299              
300             version 0.27
301              
302             =head1 DESCRIPTION
303              
304             =head1 METHODS
305              
306             =head2 prf_get_default
307              
308             =head2 prf_set_default
309              
310             =head2 setup_owner_type
311              
312             =head2 get_owner_type
313              
314             =head2 prf_defaults
315              
316             =head2 with_fields
317              
318             Searches the objecs with fields that match. Pass it a hash of
319             name => value pairs and it will return a resultset of all
320             the owners that match all the requirements. If you want to use
321             ilikes, you can, just like regular DBIC searches. It will figure
322             out the hard relationship stuff for you.
323              
324             my $rs = Owner->with_fields({
325             'simple_test' => 'test',
326             'second_test' => { -ilike => 'test2' },
327             });
328              
329             =head2 validate_extra_parameters
330              
331             =head2 validate_extra_parameter
332              
333             =head2 join_by_name
334              
335             Returns a resultset joined to the preferences with the name specified.
336              
337             $rs->join_by_name('test');
338              
339             =head2 select_extra_fields
340              
341             Returns a resultset joined to the preferences with the names specified.
342             Similar to join_by_name but it makes multiple joins for each name.
343              
344             It returns the new resultset and a list of the field -> aliases so that
345             you can then do whatever you want with them.
346              
347             my $info = $rs->select_extra_fields('test', 'test2');
348             my $new_rs = $info->{rs};
349             my $aliases = $info->{aliases};
350              
351             =head2 prefetch_extra_fields
352              
353             Select the extra fields when searching the resultset.
354             It select's them as C<extra_$fieldname>. These values are
355             accessible via C<get_column>
356              
357             It returns a hashref like L<select_extra_fields> with rs and an alias map.
358              
359             my $info = $rs->prefetch_extra_fields('field1', 'field2');
360             my $new_rs = $info->{rs};
361             my @all = $new_rs->all;
362             my $field1 = $all[0]->get_column('extra_field1');
363              
364             =head2 prf_preferences
365              
366             Returns a resultset of all the preferences relating to this type of PrfOwner.
367              
368             =head1 ATTRIBUTES
369              
370             =head1 LICENSE AND COPYRIGHT
371              
372             Copyright 2012 OpusVL.
373              
374             This software is licensed according to the "IP Assignment Schedule" provided with the development project.
375              
376             =head1 AUTHOR
377              
378             OpusVL - www.opusvl.com
379              
380             =head1 COPYRIGHT AND LICENSE
381              
382             This software is copyright (c) 2011 by OpusVL - www.opusvl.com.
383              
384             This is free software; you can redistribute it and/or modify it under
385             the same terms as the Perl 5 programming language system itself.
386              
387             =cut