Revision e5fdc4f2
Von Sven Schöling vor etwa 13 Jahren hinzugefügt
SL/Controller/Helper/ParseFilter.pm | ||
---|---|---|
36 | 36 |
|
37 | 37 |
my $query = _parse_filter($flattened, %params); |
38 | 38 |
|
39 |
_launder_keys($filter) unless $params{no_launder}; |
|
39 |
_launder_keys($filter, $params{launder_to}) unless $params{no_launder};
|
|
40 | 40 |
|
41 | 41 |
return |
42 | 42 |
($query && @$query ? (query => $query) : ()), |
... | ... | |
44 | 44 |
} |
45 | 45 |
|
46 | 46 |
sub _launder_keys { |
47 |
my ($filter) = @_; |
|
47 |
my ($filter, $launder_to) = @_; |
|
48 |
$launder_to ||= $filter; |
|
48 | 49 |
return unless ref $filter eq 'HASH'; |
49 |
my @keys = keys %$filter; |
|
50 |
for my $key (@keys) { |
|
50 |
for my $key (keys %$filter) { |
|
51 | 51 |
my $orig = $key; |
52 | 52 |
$key =~ s/:/_/g; |
53 |
$filter->{$key} = $filter->{$orig}; |
|
54 |
_launder_keys($filter->{$key}); |
|
53 |
if ('' eq ref $filter->{$orig}) { |
|
54 |
$launder_to->{$key} = $filter->{$orig}; |
|
55 |
} elsif ('ARRAY' eq ref $filter->{$orig}) { |
|
56 |
$launder_to->{$key} = [ @{ $filter->{$orig} } ]; |
|
57 |
} else { |
|
58 |
$launder_to->{$key} ||= { }; |
|
59 |
_launder_keys($filter->{$key}, $launder_to->{$key}); |
|
60 |
} |
|
55 | 61 |
}; |
56 |
|
|
57 |
return $filter; |
|
58 | 62 |
} |
59 | 63 |
|
60 | 64 |
sub _pre_parse { |
61 | 65 |
my ($filter, $with_objects, $prefix, %params) = @_; |
62 | 66 |
|
63 |
return () unless 'HASH' eq ref $filter; |
|
67 |
return (undef, $with_objects) unless 'HASH' eq ref $filter;
|
|
64 | 68 |
$with_objects ||= []; |
65 | 69 |
|
66 | 70 |
my @result; |
... | ... | |
207 | 211 |
The special empty method will be used to set the method for the previous |
208 | 212 |
method-less input. |
209 | 213 |
|
210 |
=item Laundering filter |
|
214 |
=back |
|
215 |
|
|
216 |
=head1 LAUNDERING |
|
211 | 217 |
|
212 | 218 |
Unfortunately Template cannot parse the postfixes if you want to |
213 | 219 |
rerender the filter. For this reason all colons filter keys are by |
214 |
default laundered into underscores. If you don't want this to happen |
|
215 |
pass C<< no_launder => 1 >> as a parameter. A full select_tag then |
|
216 |
loks like this: |
|
220 |
default laundered into underscores, so you can use them like this: |
|
217 | 221 |
|
218 | 222 |
[% L.input_tag('filter.price:number::lt', filter.price_number__lt) %] |
219 | 223 |
|
224 |
All of your original entries will stay intactg. If you don't want this to |
|
225 |
happen pass C<< no_launder => 1 >> as a parameter. Additionally you can pass a |
|
226 |
different target for the laundered values with the C<launder_to> parameter. It |
|
227 |
takes an hashref and will deep copy all values in your filter to the target. So |
|
228 |
if you have a filter that looks liek this: |
|
220 | 229 |
|
221 |
=back |
|
230 |
$filter = { |
|
231 |
'price:number::lt' => '2,30', |
|
232 |
'closed => '1', |
|
233 |
} |
|
234 |
|
|
235 |
and parse it with |
|
236 |
|
|
237 |
parse_filter($filter, launder_to => $laundered_filter = { }) |
|
238 |
|
|
239 |
the original filter will be unchanged, and C<$laundered_filter> will end up |
|
240 |
like this: |
|
241 |
|
|
242 |
$filter = { |
|
243 |
'price_number__lt' => '2,30', |
|
244 |
'closed => '1', |
|
245 |
} |
|
222 | 246 |
|
223 | 247 |
=head1 FILTERS (leading with :) |
224 | 248 |
|
t/controllers/helpers/parse_filter.t | ||
---|---|---|
1 | 1 |
use lib 't'; |
2 | 2 |
|
3 |
use Test::More tests => 13;
|
|
3 |
use Test::More tests => 17;
|
|
4 | 4 |
use Test::Deep; |
5 | 5 |
use Data::Dumper; |
6 | 6 |
|
... | ... | |
12 | 12 |
Support::TestSetup::login(); |
13 | 13 |
my ($filter, $expected); |
14 | 14 |
|
15 |
sub test ($$$) { |
|
16 |
my $got = { parse_filter($_[0]) }; |
|
15 |
sub test ($$$;%) { |
|
16 |
my ($filter, $expect, $msg, %params) = @_; |
|
17 |
my $target = delete $params{target}; |
|
18 |
my $args = { parse_filter($filter, %params) }; |
|
19 |
my $got = $args; |
|
20 |
$got = $filter if $target =~ /filter/; |
|
21 |
$got = $params{launder_to} if $target =~ /launder/; |
|
17 | 22 |
cmp_deeply( |
18 | 23 |
$got, |
19 |
$_[1],
|
|
20 |
$_[2]
|
|
24 |
$expect,
|
|
25 |
$msg,
|
|
21 | 26 |
) or do { |
22 |
print STDERR "expected => ", Dumper($_[1]), "\ngot: => ", Dumper($got), $/;
|
|
27 |
print STDERR "expected => ", Dumper($expect), "\ngot: => ", Dumper($got), $/;
|
|
23 | 28 |
} |
24 | 29 |
} |
25 | 30 |
|
... | ... | |
126 | 131 |
], |
127 | 132 |
}, 'arrays with filter'; |
128 | 133 |
|
134 |
|
|
135 |
########### laundering |
|
136 |
|
|
137 |
test { |
|
138 |
'sellprice:number' => [ |
|
139 |
'123,4', '2,34', '0,4', |
|
140 |
] |
|
141 |
}, { |
|
142 |
'sellprice:number' => [ '123,4', '2,34', '0,4' ], |
|
143 |
'sellprice_number' => [ '123,4', '2,34', '0,4' ], |
|
144 |
}, 'laundering with array', target => 'filter'; |
|
145 |
|
|
146 |
my %args = ( |
|
147 |
'sellprice:number' => [ |
|
148 |
'123,4', '2,34', '0,4', |
|
149 |
], |
|
150 |
); |
|
151 |
test { |
|
152 |
%args, |
|
153 |
}, { |
|
154 |
%args |
|
155 |
}, 'laundering into launder does not alter filter', target => 'filter', launder_to => {}; |
|
156 |
|
|
157 |
|
|
158 |
test { |
|
159 |
part => { |
|
160 |
'sellprice:number' => '123,4', |
|
161 |
} |
|
162 |
}, { |
|
163 |
part => { |
|
164 |
'sellprice:number' => '123,4', |
|
165 |
'sellprice_number' => '123,4' |
|
166 |
} |
|
167 |
}, 'deep laundering', target => 'filter'; |
|
168 |
|
|
169 |
|
|
170 |
test { |
|
171 |
part => { |
|
172 |
'sellprice:number' => '123,4', |
|
173 |
} |
|
174 |
}, { |
|
175 |
part => { |
|
176 |
'sellprice_number' => '123,4' |
|
177 |
} |
|
178 |
}, 'deep laundering, check for laundered hash', target => 'launder', launder_to => { }; |
|
179 |
|
Auch abrufbar als: Unified diff
ParseFilter: Laundering in explizite Ziele