From 3e988f3db569f269c7f1a4040f5dd4c9c5ebf2e6 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Fri, 3 Jul 2015 16:20:53 +0200 Subject: [PATCH] =?utf8?q?ParseFilter:=20Komplexe=20Methoden=20erm=C3=B6gl?= =?utf8?q?ichen,=20die=20auch=20den=20Key=20=C3=A4ndern?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- SL/Controller/Helper/ParseFilter.pm | 37 ++++++++++++++++++++++++---- t/controllers/helpers/parse_filter.t | 17 ++++++++++++- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/SL/Controller/Helper/ParseFilter.pm b/SL/Controller/Helper/ParseFilter.pm index 699011d01..2ff97987c 100644 --- a/SL/Controller/Helper/ParseFilter.pm +++ b/SL/Controller/Helper/ParseFilter.pm @@ -12,6 +12,14 @@ use SL::MoreCommon qw(listify); use Data::Dumper; use Text::ParseWords; +sub _lazy_bool_eq { + my ($key, $value) = @_; + + return () if ($value // '') eq ''; + return (or => [ $key => undef, $key => 0 ]) if !$value; + return ($key => 1); +} + my %filters = ( date => sub { DateTime->from_lxoffice($_[0]) }, number => sub { $::form->parse_amount(\%::myconfig, $_[0]) }, @@ -32,6 +40,10 @@ my %methods = ( } qw(similar match imatch regex regexp like ilike rlike is is_not ne eq lt gt le ge), ); +my %complex_methods = ( + lazy_bool_eq => \&_lazy_bool_eq, +); + sub parse_filter { my ($filter, %params) = @_; @@ -99,12 +111,13 @@ sub _parse_filter { $flattened = _collapse_indirect_filters($flattened); - my $all_filters = { %filters, %{ $params{filters} || {} } }; - my $all_methods = { %methods, %{ $params{methods} || {} } }; + my $all_filters = { %filters, %{ $params{filters} || {} } }; + my $all_methods = { %methods, %{ $params{methods} || {} } }; + my $all_complex = { %complex_methods, %{ $params{complex_methods} || {} } }; my @result; for (my $i = 0; $i < scalar @$flattened; $i += 2) { - my (@args, @filters, @methods); + my (@args, @filters, $method); my ($key, $value) = ($flattened->[$i], $flattened->[$i+1]); my ($type, $op) = $key =~ m{:(.+)::(.+)}; @@ -112,7 +125,7 @@ sub _parse_filter { my $is_multi = $key =~ s/:multi//; my @value_tokens = $is_multi ? parse_line('\s+', 0, $value) : ($value); - ($key, @methods) = split m{::}, $key; + ($key, $method) = split m{::}, $key, 2; ($key, @filters) = split m{:}, $key; my $orig_key = $key; @@ -121,7 +134,8 @@ sub _parse_filter { $key = $orig_key; $value_token = _apply($value_token, $_, $all_filters) for @filters; - $value_token = _apply($value_token, $_, $all_methods) for @methods; + $value_token = _apply($value_token, $method, $all_methods) if $method && exists $all_methods->{$method}; + ($key, $value_token) = _apply_complex($key, $value_token, $method, $all_complex) if $method && exists $all_complex->{$method}; ($key, $value_token) = _dispatch_custom_filters($params{class}, $with_objects, $key, $value_token) if $params{class}; ($key, $value_token) = _apply_value_filters($key, $value_token, $type, $op); @@ -246,6 +260,12 @@ sub _apply { return $filters->{$name}->($value); } +sub _apply_complex { + my ($key, $value, $name, $filters) = @_; + return $key, $value unless $name && $filters->{$name}; + return $filters->{$name}->($key, $value); +} + 1; __END__ @@ -445,6 +465,13 @@ standard SQL C<=> operator. All these are recognized like the L methods. +=item lazu_bool_eq + +If the value is undefined or an empty string then this parameter will +be completely removed from the query. Otherwise a falsish filter value +will match for C and C; trueish values will only match +C. + =back =head1 BUGS AND CAVEATS diff --git a/t/controllers/helpers/parse_filter.t b/t/controllers/helpers/parse_filter.t index aa8856ab4..2c10d036b 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 => 37; +use Test::More tests => 38; use Test::Deep; use Data::Dumper; @@ -405,3 +405,18 @@ test { 'orderitems.part.test' => { 'what', { ilike => '%2%' } }, ] }, 'relationship + additional tokens + filters + methods', class => 'SL::DB::Manager::Order'; + +test { + part => { + 'obsolete::lazy_bool_eq' => '0', + }, +}, { + query => [ + or => [ + 'part.obsolete' => undef, + 'part.obsolete' => 0 + ], + ], + with_objects => [ 'part' ], +}, 'complex methods modifying the key'; + -- 2.20.1