X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FController%2FHelper%2FParseFilter.pm;h=3bf1b65957fda6b0dada84372763096184edda34;hb=4a5e3c2cddaae9021659466eb6ad152bfdcbab9b;hp=3753d1618554667376af3e92176da32c704a6a5f;hpb=45970e731c7e0c8a3d469a1c344af20c18987c20;p=kivitendo-erp.git diff --git a/SL/Controller/Helper/ParseFilter.pm b/SL/Controller/Helper/ParseFilter.pm index 3753d1618..3bf1b6595 100644 --- a/SL/Controller/Helper/ParseFilter.pm +++ b/SL/Controller/Helper/ParseFilter.pm @@ -20,11 +20,13 @@ my %filters = ( ); my %methods = ( - lt => sub { +{ lt => $_[0] } }, - gt => sub { +{ gt => $_[0] } }, - ilike => sub { +{ ilike => $_[0] } }, - like => sub { +{ like => $_[0] } }, enable => sub { ;;;; }, + map { + # 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), ); sub parse_filter { @@ -36,7 +38,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 +46,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; @@ -70,7 +76,7 @@ sub _pre_parse { if ('HASH' eq ref $value) { my ($query, $more_objects) = _pre_parse($value, $with_objects, _prefix($prefix, $key)); push @result, @$query if $query; - push @$with_objects, $key, ($more_objects ? @$more_objects : ()); + push @$with_objects, _prefix($prefix, $key), ($more_objects ? @$more_objects : ()); } else { push @result, _prefix($prefix, $key) => $value; } @@ -207,18 +213,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 :)