Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 3e988f3d

Von Moritz Bunkus vor mehr als 9 Jahren hinzugefügt

  • ID 3e988f3db569f269c7f1a4040f5dd4c9c5ebf2e6
  • Vorgänger 585dc465
  • Nachfolger fe847cb2

ParseFilter: Komplexe Methoden ermöglichen, die auch den Key ändern

Unterschiede anzeigen:

SL/Controller/Helper/ParseFilter.pm
12 12
use Data::Dumper;
13 13
use Text::ParseWords;
14 14

  
15
sub _lazy_bool_eq {
16
  my ($key, $value) = @_;
17

  
18
  return ()                                   if ($value // '') eq '';
19
  return (or => [ $key => undef, $key => 0 ]) if !$value;
20
  return ($key => 1);
21
}
22

  
15 23
my %filters = (
16 24
  date    => sub { DateTime->from_lxoffice($_[0]) },
17 25
  number  => sub { $::form->parse_amount(\%::myconfig, $_[0]) },
......
32 40
  } qw(similar match imatch regex regexp like ilike rlike is is_not ne eq lt gt le ge),
33 41
);
34 42

  
43
my %complex_methods = (
44
  lazy_bool_eq => \&_lazy_bool_eq,
45
);
46

  
35 47
sub parse_filter {
36 48
  my ($filter, %params) = @_;
37 49

  
......
99 111

  
100 112
  $flattened = _collapse_indirect_filters($flattened);
101 113

  
102
  my $all_filters = { %filters, %{ $params{filters} || {} } };
103
  my $all_methods = { %methods, %{ $params{methods} || {} } };
114
  my $all_filters = { %filters,         %{ $params{filters}         || {} } };
115
  my $all_methods = { %methods,         %{ $params{methods}         || {} } };
116
  my $all_complex = { %complex_methods, %{ $params{complex_methods} || {} } };
104 117

  
105 118
  my @result;
106 119
  for (my $i = 0; $i < scalar @$flattened; $i += 2) {
107
    my (@args, @filters, @methods);
120
    my (@args, @filters, $method);
108 121

  
109 122
    my ($key, $value) = ($flattened->[$i], $flattened->[$i+1]);
110 123
    my ($type, $op)   = $key =~ m{:(.+)::(.+)};
......
112 125
    my $is_multi      = $key =~ s/:multi//;
113 126
    my @value_tokens  = $is_multi ? parse_line('\s+', 0, $value) : ($value);
114 127

  
115
    ($key, @methods)  = split m{::}, $key;
128
    ($key, $method)   = split m{::}, $key, 2;
116 129
    ($key, @filters)  = split m{:},  $key;
117 130

  
118 131
    my $orig_key      = $key;
......
121 134
      $key                 = $orig_key;
122 135

  
123 136
      $value_token         = _apply($value_token, $_, $all_filters) for @filters;
124
      $value_token         = _apply($value_token, $_, $all_methods) for @methods;
137
      $value_token         = _apply($value_token, $method, $all_methods)                                 if $method && exists $all_methods->{$method};
138
      ($key, $value_token) = _apply_complex($key, $value_token, $method, $all_complex)                   if $method && exists $all_complex->{$method};
125 139
      ($key, $value_token) = _dispatch_custom_filters($params{class}, $with_objects, $key, $value_token) if $params{class};
126 140
      ($key, $value_token) = _apply_value_filters($key, $value_token, $type, $op);
127 141

  
......
246 260
  return $filters->{$name}->($value);
247 261
}
248 262

  
263
sub _apply_complex {
264
  my ($key, $value, $name, $filters) = @_;
265
  return $key, $value unless $name && $filters->{$name};
266
  return $filters->{$name}->($key, $value);
267
}
268

  
249 269
1;
250 270

  
251 271
__END__
......
445 465

  
446 466
All these are recognized like the L<Rose::DB::Object> methods.
447 467

  
468
=item lazu_bool_eq
469

  
470
If the value is undefined or an empty string then this parameter will
471
be completely removed from the query. Otherwise a falsish filter value
472
will match for C<NULL> and C<FALSE>; trueish values will only match
473
C<TRUE>.
474

  
448 475
=back
449 476

  
450 477
=head1 BUGS AND CAVEATS
t/controllers/helpers/parse_filter.t
1 1
use lib 't';
2 2

  
3
use Test::More tests => 37;
3
use Test::More tests => 38;
4 4
use Test::Deep;
5 5
use Data::Dumper;
6 6

  
......
405 405
    'orderitems.part.test' => { 'what', { ilike => '%2%' } },
406 406
  ]
407 407
}, 'relationship + additional tokens + filters + methods', class => 'SL::DB::Manager::Order';
408

  
409
test {
410
  part => {
411
    'obsolete::lazy_bool_eq' => '0',
412
  },
413
}, {
414
  query => [
415
      or => [
416
        'part.obsolete' => undef,
417
        'part.obsolete' => 0
418
      ],
419
  ],
420
  with_objects => [ 'part' ],
421
}, 'complex methods modifying the key';
422

  

Auch abrufbar als: Unified diff