summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xBugzilla/Bug.pm25
-rw-r--r--Bugzilla/Constants.pm2
-rw-r--r--Bugzilla/Field.pm3
-rw-r--r--Bugzilla/Util.pm17
-rw-r--r--template/en/default/bug/field.html.tmpl6
-rw-r--r--template/en/default/global/field-descs.none.tmpl1
-rw-r--r--template/en/default/global/user-error.html.tmpl7
7 files changed, 59 insertions, 2 deletions
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm
index ed398f0fe..ba66e846f 100755
--- a/Bugzilla/Bug.pm
+++ b/Bugzilla/Bug.pm
@@ -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;
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index 827bb2d4b..12d54abee 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -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;
diff --git a/Bugzilla/Field.pm b/Bugzilla/Field.pm
index 34a1818de..5ad5e51d3 100644
--- a/Bugzilla/Field.pm
+++ b/Bugzilla/Field.pm
@@ -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;
}
diff --git a/Bugzilla/Util.pm b/Bugzilla/Util.pm
index 5c68a9092..ffc2af95a 100644
--- a/Bugzilla/Util.pm
+++ b/Bugzilla/Util.pm
@@ -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]/;
}
diff --git a/template/en/default/bug/field.html.tmpl b/template/en/default/bug/field.html.tmpl
index 7de659742..f79af3541 100644
--- a/template/en/default/bug/field.html.tmpl
+++ b/template/en/default/bug/field.html.tmpl
@@ -41,7 +41,11 @@
[% 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 %]"
diff --git a/template/en/default/global/field-descs.none.tmpl b/template/en/default/global/field-descs.none.tmpl
index 64bf546e6..178a68444 100644
--- a/template/en/default/global/field-descs.none.tmpl
+++ b/template/en/default/global/field-descs.none.tmpl
@@ -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",
diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl
index 77ce40f72..16bc0f7af 100644
--- a/template/en/default/global/user-error.html.tmpl
+++ b/template/en/default/global/user-error.html.tmpl
@@ -733,6 +733,13 @@
[% 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'} %]