X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FController%2FHelper%2FParseFilter.pm;h=2ff97987c727fef8b0520b4edd1add46a711201a;hb=4247547d2a925ddad7006cae89e5f9f1fda7d469;hp=cdd3eb7a75db7b7af7d080dbd03f8e487ee67622;hpb=84c2b3f270aa65978d03f82cde8136f6764406a2;p=kivitendo-erp.git diff --git a/SL/Controller/Helper/ParseFilter.pm b/SL/Controller/Helper/ParseFilter.pm index cdd3eb7a7..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,31 +111,40 @@ sub _parse_filter { $flattened = _collapse_indirect_filters($flattened); + 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, $method); + my ($key, $value) = ($flattened->[$i], $flattened->[$i+1]); my ($type, $op) = $key =~ m{:(.+)::(.+)}; - if ($key =~ s/:multi//) { - my @multi; - my $orig_key = $key; - for my $value (parse_line('\s+', 0, $value)) { - ($key, $value) = _apply_all($key, $value, qr/\b:(\w+)/, { %filters, %{ $params{filters} || {} } }); - ($key, $value) = _apply_all($key, $value, qr/\b::(\w+)/, { %methods, %{ $params{methods} || {} } }); - ($key, $value) = _dispatch_custom_filters($params{class}, $with_objects, $key, $value) if $params{class}; - ($key, $value) = _apply_value_filters($key, $value, $type, $op); - push @multi, $key, $value; - $key = $orig_key; - } - ($key, $value) = (and => \@multi); - } else { - ($key, $value) = _apply_all($key, $value, qr/\b:(\w+)/, { %filters, %{ $params{filters} || {} } }); - ($key, $value) = _apply_all($key, $value, qr/\b::(\w+)/, { %methods, %{ $params{methods} || {} } }); - ($key, $value) = _dispatch_custom_filters($params{class}, $with_objects, $key, $value) if $params{class}; - ($key, $value) = _apply_value_filters($key, $value, $type, $op); + my $is_multi = $key =~ s/:multi//; + my @value_tokens = $is_multi ? parse_line('\s+', 0, $value) : ($value); + + ($key, $method) = split m{::}, $key, 2; + ($key, @filters) = split m{:}, $key; + + my $orig_key = $key; + + for my $value_token (@value_tokens) { + $key = $orig_key; + + $value_token = _apply($value_token, $_, $all_filters) for @filters; + $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); + + push @args, $key, $value_token; } - push @result, $key, $value if defined $key; + next unless defined $key; + + push @result, $is_multi ? (and => [ @args ]) : @args; } return \@result; } @@ -239,14 +260,10 @@ sub _apply { return $filters->{$name}->($value); } -sub _apply_all { - my ($key, $value, $re, $subs) = @_; - - while ($key =~ s/$re//) { - $value = _apply($value, $1, $subs); - } - - return $key, $value; +sub _apply_complex { + my ($key, $value, $name, $filters) = @_; + return $key, $value unless $name && $filters->{$name}; + return $filters->{$name}->($key, $value); } 1; @@ -448,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