X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FController%2FHelper%2FParseFilter.pm;h=5a1c93cd944aa9993c7309af75db993d4606cd6f;hb=9fac28d83f55524f85cfa32cab463e0b8c063d92;hp=61b819c8804dbb3b7d63081871451f8db7ebbff6;hpb=d13408232bfd23d718fee1bc76535196ff409880;p=kivitendo-erp.git diff --git a/SL/Controller/Helper/ParseFilter.pm b/SL/Controller/Helper/ParseFilter.pm index 61b819c88..5a1c93cd9 100644 --- a/SL/Controller/Helper/ParseFilter.pm +++ b/SL/Controller/Helper/ParseFilter.pm @@ -22,7 +22,10 @@ my %filters = ( my %methods = ( enable => sub { ;;;; }, map { - $_ => sub { +{ $_ => $_[0] } }, + # since $_ is an alias it can't be used in a closure. even "".$_ or "$_" + # does not work, we need a real copy. + my $_copy = "$_"; + $_ => sub { +{ $_copy => $_[0] } }, } qw(similar match imatch regex regexp like ilike rlike is is_not ne eq lt gt le ge), ); @@ -87,21 +90,48 @@ sub _parse_filter { return () unless 'ARRAY' eq ref $flattened; - my %sorted = ( @$flattened ); + $flattened = _collapse_indirect_filters($flattened); + + my @result; + for (my $i = 0; $i < scalar @$flattened; $i += 2) { + my ($key, $value) = ($flattened->[$i], $flattened->[$i+1]); + ($key, $value) = _apply_all($key, $value, qr/\b:(\w+)/, { %filters, %{ $params{filters} || {} } }); + ($key, $value) = _apply_all($key, $value, qr/\b::(\w+)/, { %methods, %{ $params{methods} || {} } }); + push @result, $key, $value; + } + return \@result; +} + +sub _collapse_indirect_filters { + my ($flattened) = @_; + + die 'flattened filter array length is uneven, should be possible to use as hash' if @$flattened % 2; + + my (%keys_to_delete, %keys_to_move, @collapsed); + + # search keys matching /::$/; + for (my $i = 0; $i < scalar @$flattened; $i += 2) { + my ($key, $value) = ($flattened->[$i], $flattened->[$i+1]); - my @keys = sort { length($b) <=> length($a) } keys %sorted; - for my $key (@keys) { next unless $key =~ /^(.*\b)::$/; - $sorted{$1 . '::' . delete $sorted{$key} } = delete $sorted{$1} if $sorted{$1} && $sorted{$key}; + + $keys_to_delete{$key}++; + $keys_to_move{$1} = $1 . '::' . $value; } - my %result; - while (my ($key, $value) = each %sorted) { - ($key, $value) = _apply_all($key, $value, qr/\b:(\w+)/, { %filters, %{ $params{filters} || {} } }); - ($key, $value) = _apply_all($key, $value, qr/\b::(\w+)/, { %methods, %{ $params{methods} || {} } }); - $result{$key} = $value; + for (my $i = 0; $i < scalar @$flattened; $i += 2) { + my ($key, $value) = ($flattened->[$i], $flattened->[$i+1]); + + if ($keys_to_move{$key}) { + push @collapsed, $keys_to_move{$key}, $value; + next; + } + if (!$keys_to_delete{$key}) { + push @collapsed, $key, $value; + } } - return [ %result ]; + + return \@collapsed; } sub _prefix {