From e5fdc4f27f18beeffbb1510f2fa6ee545087ea49 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sven=20Sch=C3=B6ling?= Date: Wed, 14 Dec 2011 15:47:10 +0100 Subject: [PATCH] ParseFilter: Laundering in explizite Ziele --- SL/Controller/Helper/ParseFilter.pm | 52 ++++++++++++++++------- t/controllers/helpers/parse_filter.t | 63 +++++++++++++++++++++++++--- 2 files changed, 95 insertions(+), 20 deletions(-) diff --git a/SL/Controller/Helper/ParseFilter.pm b/SL/Controller/Helper/ParseFilter.pm index 3753d1618..ac086f594 100644 --- a/SL/Controller/Helper/ParseFilter.pm +++ b/SL/Controller/Helper/ParseFilter.pm @@ -36,7 +36,7 @@ sub parse_filter { 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) : ()), @@ -44,23 +44,27 @@ sub parse_filter { } 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; @@ -207,18 +211,38 @@ and later 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 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 :) diff --git a/t/controllers/helpers/parse_filter.t b/t/controllers/helpers/parse_filter.t index 84547e05b..179c236c9 100644 --- a/t/controllers/helpers/parse_filter.t +++ b/t/controllers/helpers/parse_filter.t @@ -1,6 +1,6 @@ use lib 't'; -use Test::More tests => 13; +use Test::More tests => 17; use Test::Deep; use Data::Dumper; @@ -12,14 +12,19 @@ undef *::any; # Test::Deep exports any (for junctions) and MoreCommon exports an 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), $/; } } @@ -126,3 +131,49 @@ test { ], }, '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 => { }; + -- 2.20.1