Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision d2550089

Von Sven Schöling vor mehr als 11 Jahren hinzugefügt

  • ID d2550089aa9f5d321e025df59815b0eabc7037ab
  • Vorgänger a45d8cbe
  • Nachfolger 10ca9778

Besseres Objektverhalten und bessere Doku für ParseFilter

ausserdem Arraylaundering

Unterschiede anzeigen:

SL/Controller/Helper/ParseFilter.pm
33 33
  my ($filter, %params) = @_;
34 34

  
35 35
  my $hint_objects = $params{with_objects} || [];
36
  my $auto_objects = [];
36 37

  
37
  my ($flattened, $objects) = _pre_parse($filter, $hint_objects, '', %params);
38
  my ($flattened, $objects) = flatten($filter, $auto_objects, '', %params);
38 39

  
39
  my $query = _parse_filter($flattened, %params);
40
  if ($params{class}) {
41
    $objects = $hint_objects;
42
  }
43

  
44
  my $query = _parse_filter($flattened, $objects, %params);
40 45

  
41 46
  _launder_keys($filter, $params{launder_to}) unless $params{no_launder};
42 47

  
......
55 60
    if ('' eq ref $filter->{$orig}) {
56 61
      $launder_to->{$key} = $filter->{$orig};
57 62
    } elsif ('ARRAY' eq ref $filter->{$orig}) {
58
      $launder_to->{$key} = [ @{ $filter->{$orig} } ];
63
      $launder_to->{"${key}_"} = { map { $_ => 1 } @{ $filter->{$orig} } };
59 64
    } else {
60 65
      $launder_to->{$key} ||= { };
61 66
      _launder_keys($filter->{$key}, $launder_to->{$key});
......
63 68
  };
64 69
}
65 70

  
66
sub _pre_parse {
71
sub flatten {
67 72
  my ($filter, $with_objects, $prefix, %params) = @_;
68 73

  
69 74
  return (undef, $with_objects) unless 'HASH'  eq ref $filter;
......
74 79
  while (my ($key, $value) = each %$filter) {
75 80
    next if !defined $value || $value eq ''; # 0 is fine
76 81
    if ('HASH' eq ref $value) {
77
      my ($query, $more_objects) = _pre_parse($value, $with_objects, _prefix($prefix, $key));
82
      my ($query, $more_objects) = flatten($value, $with_objects, _prefix($prefix, $key));
78 83
      push @result,        @$query if $query;
79 84
      push @$with_objects, _prefix($prefix, $key), ($more_objects ? @$more_objects : ());
80 85
    } else {
......
86 91
}
87 92

  
88 93
sub _parse_filter {
89
  my ($flattened, %params) = @_;
94
  my ($flattened, $with_objects, %params) = @_;
90 95

  
91 96
  return () unless 'ARRAY' eq ref $flattened;
92 97

  
......
98 103

  
99 104
    ($key, $value) = _apply_all($key, $value, qr/\b:(\w+)/,  { %filters, %{ $params{filters} || {} } });
100 105
    ($key, $value) = _apply_all($key, $value, qr/\b::(\w+)/, { %methods, %{ $params{methods} || {} } });
101
    ($key, $value) = _dispatch_custom_filters($params{class}, $key, $value) if $params{class};
106
    ($key, $value) = _dispatch_custom_filters($params{class}, $with_objects, $key, $value) if $params{class};
102 107

  
103 108
    push @result, $key, $value;
104 109
  }
......
106 111
}
107 112

  
108 113
sub _dispatch_custom_filters {
109
  my ($class, $key, $value) = @_;
114
  my ($class, $with_objects, $key, $value) = @_;
110 115

  
111 116
  # the key should by now have no filters left
112 117
  # if it has, catch it here:
......
126 131
    }
127 132
  }
128 133

  
129
  my $manager = $curr_class->meta->convention_manager->auto_manager_class_name;
134
  my $manager    = $curr_class->meta->convention_manager->auto_manager_class_name;
135
  my $obj_path   = join '.', @tokens;
136
  my $obj_prefix = join '.', @tokens, '';
130 137

  
131 138
  if ($manager->can('filter')) {
132
    ($key, $value) = $manager->filter($last_token, $value, join '.', @tokens, '');
139
    ($key, $value, my $obj) = $manager->filter($last_token, $value, $obj_prefix);
140
    _add_uniq($with_objects, $obj);
141
  } else {
142
    _add_uniq($with_objects, $obj_path);
133 143
  }
134 144

  
135 145
  return ($key, $value);
136 146
}
137 147

  
148
sub _add_uniq {
149
   my ($array, $what) = @_;
150

  
151
   $array //= [];
152
   $array = [ uniq @$array, $what ];
153
}
154

  
138 155
sub _collapse_indirect_filters {
139 156
  my ($flattened) = @_;
140 157

  
......
270 287

  
271 288
  [% L.input_tag('filter.price:number::lt', filter.price_number__lt) %]
272 289

  
273
All of your original entries will stay intactg. If you don't want this to
290
Also Template has trouble when looking up the contents of arrays, so
291
these will get copied into a _ suffixed version as hashes:
292

  
293
  [% L.checkbox_tag('filter.ids[]', value=15, checked=filter.ids_.15) %]
294

  
295
All of your original entries will stay intact. If you don't want this to
274 296
happen pass C<< no_launder => 1 >> as a parameter.  Additionally you can pass a
275 297
different target for the laundered values with the C<launder_to>  parameter. It
276 298
takes an hashref and will deep copy all values in your filter to the target. So
277
if you have a filter that looks liek this:
299
if you have a filter that looks like this:
278 300

  
279 301
  $filter = {
280 302
    'price:number::lt' => '2,30',
281
    'closed            => '1',
303
    closed             => '1',
304
    type               => [ 'part', 'assembly' ],
282 305
  }
283 306

  
284 307
and parse it with
......
290 313

  
291 314
  $filter = {
292 315
    'price_number__lt' => '2,30',
293
    'closed            => '1',
316
     closed            => '1',
317
    'type_'            => { part => 1, assembly => 1 },
294 318
  }
295 319

  
296 320
=head1 INDIRECT FILTER METHODS
t/controllers/helpers/parse_filter.t
142 142
  ]
143 143
}, {
144 144
  'sellprice:number' => [ '123,4', '2,34', '0,4' ],
145
  'sellprice_number' => [ '123,4', '2,34', '0,4' ],
145
  'sellprice_number' => { '123,4' => 1, '2,34' => 1, '0,4' => 1 },
146 146
}, 'laundering with array', target => 'filter';
147 147

  
148 148
my %args = (

Auch abrufbar als: Unified diff