my $query = _parse_filter($flattened, %params);
- _launder_keys($filter) unless $params{no_launder};
+ _launder_keys($filter, $params{launder_to}) unless $params{no_launder};
return
($query && @$query ? (query => $query) : ()),
}
sub _launder_keys {
- my ($filter) = @_;
+ my ($filter, $launder_to) = @_;
+ $launder_to ||= $filter;
return unless ref $filter eq 'HASH';
- my @keys = keys %$filter;
- for my $key (@keys) {
+ for my $key (keys %$filter) {
my $orig = $key;
$key =~ s/:/_/g;
- $filter->{$key} = $filter->{$orig};
- _launder_keys($filter->{$key});
+ if ('' eq ref $filter->{$orig}) {
+ $launder_to->{$key} = $filter->{$orig};
+ } elsif ('ARRAY' eq ref $filter->{$orig}) {
+ $launder_to->{$key} = [ @{ $filter->{$orig} } ];
+ } else {
+ $launder_to->{$key} ||= { };
+ _launder_keys($filter->{$key}, $launder_to->{$key});
+ }
};
-
- return $filter;
}
sub _pre_parse {
my ($filter, $with_objects, $prefix, %params) = @_;
- return () unless 'HASH' eq ref $filter;
+ return (undef, $with_objects) unless 'HASH' eq ref $filter;
$with_objects ||= [];
my @result;
The special empty method will be used to set the method for the previous
method-less input.
-=item Laundering filter
+=back
+
+=head1 LAUNDERING
Unfortunately Template cannot parse the postfixes if you want to
rerender the filter. For this reason all colons filter keys are by
-default laundered into underscores. If you don't want this to happen
-pass C<< no_launder => 1 >> as a parameter. A full select_tag then
-loks like this:
+default laundered into underscores, so you can use them like this:
[% L.input_tag('filter.price:number::lt', filter.price_number__lt) %]
+All of your original entries will stay intactg. If you don't want this to
+happen pass C<< no_launder => 1 >> as a parameter. Additionally you can pass a
+different target for the laundered values with the C<launder_to> parameter. It
+takes an hashref and will deep copy all values in your filter to the target. So
+if you have a filter that looks liek this:
-=back
+ $filter = {
+ 'price:number::lt' => '2,30',
+ 'closed => '1',
+ }
+
+and parse it with
+
+ parse_filter($filter, launder_to => $laundered_filter = { })
+
+the original filter will be unchanged, and C<$laundered_filter> will end up
+like this:
+
+ $filter = {
+ 'price_number__lt' => '2,30',
+ 'closed => '1',
+ }
=head1 FILTERS (leading with :)
use lib 't';
-use Test::More tests => 13;
+use Test::More tests => 17;
use Test::Deep;
use Data::Dumper;
Support::TestSetup::login();
my ($filter, $expected);
-sub test ($$$) {
- my $got = { parse_filter($_[0]) };
+sub test ($$$;%) {
+ my ($filter, $expect, $msg, %params) = @_;
+ my $target = delete $params{target};
+ my $args = { parse_filter($filter, %params) };
+ my $got = $args;
+ $got = $filter if $target =~ /filter/;
+ $got = $params{launder_to} if $target =~ /launder/;
cmp_deeply(
$got,
- $_[1],
- $_[2]
+ $expect,
+ $msg,
) or do {
- print STDERR "expected => ", Dumper($_[1]), "\ngot: => ", Dumper($got), $/;
+ print STDERR "expected => ", Dumper($expect), "\ngot: => ", Dumper($got), $/;
}
}
],
}, 'arrays with filter';
+
+########### laundering
+
+test {
+ 'sellprice:number' => [
+ '123,4', '2,34', '0,4',
+ ]
+}, {
+ 'sellprice:number' => [ '123,4', '2,34', '0,4' ],
+ 'sellprice_number' => [ '123,4', '2,34', '0,4' ],
+}, 'laundering with array', target => 'filter';
+
+my %args = (
+ 'sellprice:number' => [
+ '123,4', '2,34', '0,4',
+ ],
+);
+test {
+ %args,
+}, {
+ %args
+}, 'laundering into launder does not alter filter', target => 'filter', launder_to => {};
+
+
+test {
+ part => {
+ 'sellprice:number' => '123,4',
+ }
+}, {
+ part => {
+ 'sellprice:number' => '123,4',
+ 'sellprice_number' => '123,4'
+ }
+}, 'deep laundering', target => 'filter';
+
+
+test {
+ part => {
+ 'sellprice:number' => '123,4',
+ }
+}, {
+ part => {
+ 'sellprice_number' => '123,4'
+ }
+}, 'deep laundering, check for laundered hash', target => 'launder', launder_to => { };
+