Filtered-Helfer: bei Typ 'date' und Operator 'le' Wert auf nächsten Tag ändern
authorMoritz Bunkus <m.bunkus@linet-services.de>
Mon, 6 Jan 2014 13:07:59 +0000 (14:07 +0100)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Mon, 6 Jan 2014 13:07:59 +0000 (14:07 +0100)
Ist die Datenbankspalte vom Typ 'timestamp', so sind die Timestamps am
gleichen Tag wie das zu vergleichende Argument allesamt größer als das
vergleichende Argument. Der Benutzer erwartet aufgrund von <= aber,
dass die alle mit einbezogen werden.

Workaround: für Vergleichsoperation <= bei Feldtyp 'date' einfach das
Datum auf 'Anfang des nächsten Tages' erhöhen und den Vergleich auf <
ändern. Das funktioniert sowohl bei Datenbankspalten mit Typ 'date'
als auch bei denjenigen mit Typ 'timestamp'.

Behebt #2404.

SL/Controller/Helper/ParseFilter.pm

index afe9b7b..9b5eb51 100644 (file)
@@ -101,16 +101,31 @@ sub _parse_filter {
   my @result;
   for (my $i = 0; $i < scalar @$flattened; $i += 2) {
     my ($key, $value) = ($flattened->[$i], $flattened->[$i+1]);
+    my ($type, $op)   = $key =~ m{:(.+)::(.+)};
 
     ($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 @result, $key, $value if defined $key;
   }
   return \@result;
 }
 
+sub _apply_value_filters {
+  my ($key, $value, $type, $op) = @_;
+
+  return ($key, $value) unless $key && $value && $type && $op && (ref($value) eq 'HASH');
+
+  if (($type eq 'date') && ($op eq 'le')) {
+    my $date     = delete $value->{le};
+    $value->{lt} = $date->add(days => 1);
+  }
+
+  return ($key, $value);
+}
+
 sub _dispatch_custom_filters {
   my ($class, $with_objects, $key, $value) = @_;