]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 357324: Date/Time Custom Fields
authormkanat%bugzilla.org <>
Wed, 24 Oct 2007 00:36:51 +0000 (00:36 +0000)
committermkanat%bugzilla.org <>
Wed, 24 Oct 2007 00:36:51 +0000 (00:36 +0000)
Patch By Max Kanat-Alexander <mkanat@bugzilla.org> r=LpSolit, a=LpSolit

Bugzilla/Bug.pm
Bugzilla/Constants.pm
Bugzilla/Field.pm
Bugzilla/Util.pm
template/en/default/bug/field.html.tmpl
template/en/default/global/field-descs.none.tmpl
template/en/default/global/user-error.html.tmpl

index ed398f0fe4e48dc1f6ade52e425dc9602b70c7aa..ba66e846fa548fb281e1ef322bfb74c7d0c3ec0a 100755 (executable)
@@ -145,6 +145,9 @@ sub VALIDATORS {
         elsif ($field->type == FIELD_TYPE_MULTI_SELECT) {
             $validator = \&_check_multi_select_field;
         }
+        elsif ($field->type == FIELD_TYPE_DATETIME) {
+            $validator = \&_check_datetime_field;
+        }
         else {
             $validator = \&_check_freetext_field;
         }
@@ -1240,6 +1243,28 @@ sub _check_work_time {
 
 # Custom Field Validators
 
+sub _check_datetime_field {
+    my ($invocant, $date_time) = @_;
+
+    # Empty datetimes are empty strings or strings only containing
+    # 0's, whitespace, and punctuation.
+    if ($date_time =~ /^[\s0[:punct:]]*$/) {
+        return undef;
+    }
+
+    $date_time = trim($date_time);
+    my ($date, $time) = split(' ', $date_time);
+    if ($date && !validate_date($date)) {
+        ThrowUserError('illegal_date', { date   => $date,
+                                         format => 'YYYY-MM-DD' });
+    }
+    if ($time && !validate_time($time)) {
+        ThrowUserError('illegal_time', { 'time' => $time,
+                                         format => 'HH:MM:SS' });
+    }
+    return $date_time
+}
+
 sub _check_multi_select_field {
     my ($invocant, $values, $field) = @_;
     return [] if !$values;
index 827bb2d4b6728fb2c83b1cd457804ec846d2794e..12d54abee0ec13353c7658ab770fecda7a9142f3 100644 (file)
@@ -121,6 +121,7 @@ use File::Basename;
     FIELD_TYPE_SINGLE_SELECT
     FIELD_TYPE_MULTI_SELECT
     FIELD_TYPE_TEXTAREA
+    FIELD_TYPE_DATETIME
 
     USAGE_MODE_BROWSER
     USAGE_MODE_CMDLINE
@@ -349,6 +350,7 @@ use constant FIELD_TYPE_FREETEXT  => 1;
 use constant FIELD_TYPE_SINGLE_SELECT => 2;
 use constant FIELD_TYPE_MULTI_SELECT => 3;
 use constant FIELD_TYPE_TEXTAREA  => 4;
+use constant FIELD_TYPE_DATETIME  => 5;
 
 # The maximum number of days a token will remain valid.
 use constant MAX_TOKEN_AGE => 3;
index 34a1818de975cb81256e389d78a7d8c1f5797e44..5ad5e51d3fad6c7a63c147258c8d6d6cabab5a52 100644 (file)
@@ -127,6 +127,7 @@ use constant SQL_DEFINITIONS => {
     FIELD_TYPE_SINGLE_SELECT, { TYPE => 'varchar(64)', NOTNULL => 1,
                                 DEFAULT => "'---'" },
     FIELD_TYPE_TEXTAREA,      { TYPE => 'MEDIUMTEXT' },
+    FIELD_TYPE_DATETIME,      { TYPE => 'DATETIME'   },
 };
 
 # Field definitions for the fields that ship with Bugzilla.
@@ -255,7 +256,7 @@ sub _check_type {
     my $saved_type = $type;
     # The constant here should be updated every time a new,
     # higher field type is added.
-    (detaint_natural($type) && $type <= FIELD_TYPE_TEXTAREA)
+    (detaint_natural($type) && $type <= FIELD_TYPE_DATETIME)
       || ThrowCodeError('invalid_customfield_type', { type => $saved_type });
     return $type;
 }
index 5c68a9092746d7e1f8ad74bc78d3b86621faf7c2..ffc2af95a73e5da0575ecc0865a25f3ef0e31291 100644 (file)
@@ -40,6 +40,7 @@ use base qw(Exporter);
                              diff_arrays diff_strings
                              trim wrap_comment find_wrap_point
                              format_time format_time_decimal validate_date
+                             validate_time
                              file_mod_time is_7bit_clean
                              bz_crypt generate_random_password
                              validate_email_syntax clean_text
@@ -457,6 +458,22 @@ sub validate_date {
     return $ret ? 1 : 0;
 }
 
+sub validate_time {
+    my ($time) = @_;
+    my $time2;
+
+    # $ts is undefined if the parser fails.
+    my $ts = str2time($time);
+    if ($ts) {
+        $time2 = time2str("%H:%M:%S", $ts);
+
+        $time  =~ s/(\d+):(\d+?):(\d+?)/$1:$2:$3/;
+        $time2 =~ s/(\d+):(\d+?):(\d+?)/$1:$2:$3/;
+    }
+    my $ret = ($ts && $time eq $time2);
+    return $ret ? 1 : 0;
+}
+
 sub is_7bit_clean {
     return $_[0] !~ /[^\x20-\x7E\x0A\x0D]/;
 }
index 7de659742f68e814451c6110bc8f86dc1c7d2084..f79af3541f62ac7b8ed2624f0e2c9757b1623f7f 100644 (file)
 [% IF editable %]
   [% SWITCH field.type %]
     [% CASE constants.FIELD_TYPE_FREETEXT %]
-        <input name="[% field.name FILTER html %]" value="[% value FILTER html %]" size="60">
+        <input name="[% field.name FILTER html %]" 
+               value="[% value FILTER html %]" size="60">
+    [% CASE constants.FIELD_TYPE_DATETIME %]
+      <input name="[% field.name FILTER html %]" size="20"
+             value="[% value FILTER html %]">
     [% CASE [ constants.FIELD_TYPE_SINGLE_SELECT 
               constants.FIELD_TYPE_MULTI_SELECT ] %]
         <select id="[% field.name FILTER html %]" 
index 64bf546e6c2d672f21494ce380cf33ab39ae3c49..178a6844445448a7234bd22f62f2c8af77e2ce22 100644 (file)
@@ -83,6 +83,7 @@
                    ${constants.FIELD_TYPE_SINGLE_SELECT} => "Drop Down",
                    ${constants.FIELD_TYPE_MULTI_SELECT}  => "Multiple-Selection Box",
                    ${constants.FIELD_TYPE_TEXTAREA}      => "Large Text Box",
+                   ${constants.FIELD_TYPE_DATETIME}      => "Date/Time",
                 } %]
 
 [% status_descs = { "UNCONFIRMED" => "UNCONFIRMED",
index 77ce40f722e8d0b3c56a581df8d7f3f8840a78d4..16bc0f7afa8a2abb89fbae75ce84ce078d9bbf07 100644 (file)
     [% docslinks = {'reporting.html' => 'Reporting'} %]
     You are not authorized to edit this series. To do this, you must either
     be its creator, or an administrator.
+
+  [% ELSIF error == "illegal_time" %]
+    [% title = "Illegal Time" %]
+    '<tt>[% time FILTER html %]</tt>' is not a legal time.
+    [% IF format %]
+      Please use the format '<tt>[% format FILTER html %]</tt>'.
+    [% END %]
         
   [% ELSIF error == "insufficient_data_points" %]
     [% docslinks = {'reporting.html' => 'Reporting'} %]