summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Bugzilla/DB.pm7
-rw-r--r--Bugzilla/DB/Oracle.pm15
-rw-r--r--Bugzilla/DB/Pg.pm12
-rw-r--r--Bugzilla/DB/Sqlite.pm6
-rw-r--r--Bugzilla/Search.pm36
-rw-r--r--Bugzilla/WebService/Bug.pm7
-rw-r--r--docs/en/xml/administration.xml15
-rwxr-xr-xemail_in.pl19
-rw-r--r--template/en/default/bug/edit.html.tmpl14
-rw-r--r--template/en/default/bug/field-label.html.tmpl3
10 files changed, 73 insertions, 61 deletions
diff --git a/Bugzilla/DB.pm b/Bugzilla/DB.pm
index a537d6131..083a1c208 100644
--- a/Bugzilla/DB.pm
+++ b/Bugzilla/DB.pm
@@ -397,8 +397,11 @@ sub sql_string_concat {
sub sql_string_until {
my ($self, $string, $substring) = @_;
- return "SUBSTRING($string FROM 1 FOR " .
- $self->sql_position($substring, $string) . " - 1)";
+
+ my $position = $self->sql_position($substring, $string);
+ return "CASE WHEN $position != 0"
+ . " THEN SUBSTR($string, 1, $position - 1)"
+ . " ELSE $string END";
}
sub sql_in {
diff --git a/Bugzilla/DB/Oracle.pm b/Bugzilla/DB/Oracle.pm
index d91eb428e..711b84141 100644
--- a/Bugzilla/DB/Oracle.pm
+++ b/Bugzilla/DB/Oracle.pm
@@ -40,6 +40,8 @@ use base qw(Bugzilla::DB);
use DBD::Oracle;
use DBD::Oracle qw(:ora_types);
+use List::Util qw(max);
+
use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::Util;
@@ -50,6 +52,8 @@ use Bugzilla::Util;
use constant EMPTY_STRING => '__BZ_EMPTY_STR__';
use constant ISOLATION_LEVEL => 'READ COMMITTED';
use constant BLOB_TYPE => { ora_type => ORA_BLOB };
+# The max size allowed for LOB fields, in kilobytes.
+use constant MIN_LONG_READ_LEN => 32 * 1024;
use constant FULLTEXT_OR => ' OR ';
sub new {
@@ -68,8 +72,8 @@ sub new {
my $dsn = "dbi:Oracle:host=$host;sid=$dbname";
$dsn .= ";port=$port" if $port;
my $attrs = { FetchHashKeyName => 'NAME_lc',
- LongReadLen => ( Bugzilla->params->{'maxattachmentsize'}
- || 1000 ) * 1024,
+ LongReadLen => max(Bugzilla->params->{'maxattachmentsize'},
+ MIN_LONG_READ_LEN) * 1024,
};
my $self = $class->db_new({ dsn => $dsn, user => $user,
pass => $pass, attrs => $attrs });
@@ -156,13 +160,6 @@ sub sql_string_concat {
return 'CONCAT(' . join(', ', @params) . ')';
}
-sub sql_string_until {
- my ($self, $string, $substring) = @_;
- return "SUBSTR($string, 1, "
- . $self->sql_position($substring, $string)
- . " - 1)";
-}
-
sub sql_to_days {
my ($self, $date) = @_;
diff --git a/Bugzilla/DB/Pg.pm b/Bugzilla/DB/Pg.pm
index 386a67709..e59a638a4 100644
--- a/Bugzilla/DB/Pg.pm
+++ b/Bugzilla/DB/Pg.pm
@@ -192,18 +192,6 @@ sub sql_string_concat {
return '(CAST(' . join(' AS text) || CAST(', @params) . ' AS text))';
}
-sub sql_string_until {
- my ($self, $string, $substring) = @_;
-
- # PostgreSQL does not permit a negative substring length; therefore we
- # use CASE to only perform the SUBSTRING operation when $substring can
- # be found withing $string.
- my $position = $self->sql_position($substring, $string);
- return "CASE WHEN $position != 0"
- . " THEN SUBSTRING($string FROM 1 FOR $position - 1)"
- . " ELSE $string END";
-}
-
# Tell us whether or not a particular sequence exists in the DB.
sub bz_sequence_exists {
my ($self, $seq_name) = @_;
diff --git a/Bugzilla/DB/Sqlite.pm b/Bugzilla/DB/Sqlite.pm
index fb6aaba97..e13fd18e1 100644
--- a/Bugzilla/DB/Sqlite.pm
+++ b/Bugzilla/DB/Sqlite.pm
@@ -237,12 +237,6 @@ sub sql_date_math {
return "DATETIME($date, '$operator' || $interval || ' $units')";
}
-sub sql_string_until {
- my ($self, $string, $substring) = @_;
- my $position = $self->sql_position($substring, $string);
- return "SUBSTR($string, 1, $position - 1)"
-}
-
###############
# bz_ methods #
###############
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm
index fdc0e2991..0c9f84689 100644
--- a/Bugzilla/Search.pm
+++ b/Bugzilla/Search.pm
@@ -55,6 +55,7 @@ use Bugzilla::Keyword;
use Data::Dumper;
use Date::Format;
use Date::Parse;
+use Scalar::Util qw(blessed);
use List::MoreUtils qw(all part uniq);
use POSIX qw(INT_MAX);
use Storable qw(dclone);
@@ -509,9 +510,14 @@ use constant COLUMN_JOINS => {
# and we don't want it to happen at compile time, so we have it as a
# subroutine.
sub COLUMNS {
+ my $invocant = shift;
+ my $user = blessed($invocant) ? $invocant->_user : Bugzilla->user;
my $dbh = Bugzilla->dbh;
my $cache = Bugzilla->request_cache;
- return $cache->{search_columns} if defined $cache->{search_columns};
+
+ if (defined $cache->{search_columns}->{$user->id}) {
+ return $cache->{search_columns}->{$user->id};
+ }
# These are columns that don't exist in fielddefs, but are valid buglist
# columns. (Also see near the bottom of this function for the definition
@@ -567,10 +573,7 @@ sub COLUMNS {
foreach my $col (@email_fields) {
my $sql = "map_${col}.login_name";
- # XXX This needs to be generated inside an accessor instead,
- # probably, because it should use $self->_user to determine
- # this, not Bugzilla->user.
- if (!Bugzilla->user->id) {
+ if (!$user->id) {
$sql = $dbh->sql_string_until($sql, $dbh->quote('@'));
}
$special_sql{$col} = $sql;
@@ -605,12 +608,15 @@ sub COLUMNS {
Bugzilla::Hook::process('buglist_columns', { columns => \%columns });
- $cache->{search_columns} = \%columns;
- return $cache->{search_columns};
+ $cache->{search_columns}->{$user->id} = \%columns;
+ return $cache->{search_columns}->{$user->id};
}
sub REPORT_COLUMNS {
- my $columns = dclone(COLUMNS);
+ my $invocant = shift;
+ my $user = blessed($invocant) ? $invocant->_user : Bugzilla->user;
+
+ my $columns = dclone(blessed($invocant) ? $invocant->COLUMNS : COLUMNS);
# There's no reason to support reporting on unique fields.
# Also, some other fields don't make very good reporting axises,
# or simply don't work with the current reporting system.
@@ -625,7 +631,7 @@ sub REPORT_COLUMNS {
# If you're not a time-tracker, you can't use time-tracking
# columns.
- if (!Bugzilla->user->is_timetracker) {
+ if (!$user->is_timetracker) {
push(@no_report_columns, TIMETRACKING_FIELDS);
}
@@ -841,7 +847,7 @@ sub _sql_select {
my $alias = $column;
# Aliases cannot contain dots in them. We convert them to underscores.
$alias =~ s/\./_/g;
- my $sql = COLUMNS->{$column}->{name} . " AS $alias";
+ my $sql = $self->COLUMNS->{$column}->{name} . " AS $alias";
push(@sql_fields, $sql);
}
return @sql_fields;
@@ -1190,7 +1196,7 @@ sub _sql_group_by {
my @extra_group_by;
foreach my $column ($self->_select_columns) {
next if $self->_skip_group_by->{$column};
- my $sql = COLUMNS->{$column}->{name};
+ my $sql = $self->COLUMNS->{$column}->{name};
push(@extra_group_by, $sql);
}
@@ -2299,11 +2305,11 @@ sub _content_matches {
#
# We build the relevance SQL by modifying the COLUMNS list directly,
# which is kind of a hack but works.
- my $current = COLUMNS->{'relevance'}->{name};
+ my $current = $self->COLUMNS->{'relevance'}->{name};
$current = $current ? "$current + " : '';
# For NOT searches, we just add 0 to the relevance.
my $select_term = $operator =~ /not/ ? 0 : "($current$rterm1 + $rterm2)";
- COLUMNS->{'relevance'}->{name} = $select_term;
+ $self->COLUMNS->{'relevance'}->{name} = $select_term;
}
sub _long_descs_count {
@@ -2353,13 +2359,13 @@ sub _work_time_changedbefore_after {
sub _work_time {
my ($self, $args) = @_;
$self->_add_extra_column('actual_time');
- $args->{full_field} = COLUMNS->{actual_time}->{name};
+ $args->{full_field} = $self->COLUMNS->{actual_time}->{name};
}
sub _percentage_complete {
my ($self, $args) = @_;
- $args->{full_field} = COLUMNS->{percentage_complete}->{name};
+ $args->{full_field} = $self->COLUMNS->{percentage_complete}->{name};
# We need actual_time in _select_columns, otherwise we can't use
# it in the expression for searching percentage_complete.
diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm
index 8506c4b47..ca9ee1014 100644
--- a/Bugzilla/WebService/Bug.pm
+++ b/Bugzilla/WebService/Bug.pm
@@ -665,9 +665,12 @@ sub add_attachment {
my @created;
$dbh->bz_start_transaction();
+ my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
+
foreach my $bug (@bugs) {
my $attachment = Bugzilla::Attachment->create({
bug => $bug,
+ creation_ts => $timestamp,
data => $params->{data},
description => $params->{summary},
filename => $params->{file_name},
@@ -682,7 +685,7 @@ sub add_attachment {
extra_data => $attachment->id });
push(@created, $attachment);
}
- $_->bug->update($_->attached) foreach @created;
+ $_->bug->update($timestamp) foreach @created;
$dbh->bz_commit_transaction();
$_->send_changes() foreach @bugs;
@@ -2541,7 +2544,7 @@ This allows you to add a comment to a bug in Bugzilla.
=over
-=item C<id> (int) B<Required> - The id or alias of the bug to append a
+=item C<id> (int or string) B<Required> - The id or alias of the bug to append a
comment to.
=item C<comment> (string) B<Required> - The comment to append to the bug.
diff --git a/docs/en/xml/administration.xml b/docs/en/xml/administration.xml
index 4b7189755..cabb772d2 100644
--- a/docs/en/xml/administration.xml
+++ b/docs/en/xml/administration.xml
@@ -2365,6 +2365,11 @@ ReadOnly: ENTRY, NA/NA, CANEDIT
several types available:
<simplelist>
<member>
+ Bug ID: A field where you can enter the ID of another bug from
+ the same Bugzilla installation. To point to a bug in a remote
+ installation, use the See Also field instead.
+ </member>
+ <member>
Large Text Box: A multiple line box for entering free text.
</member>
<member>
@@ -2427,6 +2432,16 @@ ReadOnly: ENTRY, NA/NA, CANEDIT
be displayed at all. Obsolete Custom Fields are hidden.
</para>
</listitem>
+
+ <listitem>
+ <para>
+ <emphasis>Is mandatory:</emphasis>
+ Boolean that determines whether this field must be set.
+ For single and multi-select fields, this means that a (non-default)
+ value must be selected, and for text and date fields, some text
+ must be entered.
+ </para>
+ </listitem>
</itemizedlist>
</para>
</section>
diff --git a/email_in.pl b/email_in.pl
index 55e7b119a..ed4cf9a04 100755
--- a/email_in.pl
+++ b/email_in.pl
@@ -158,22 +158,29 @@ sub parse_mail {
return \%fields;
}
-sub post_bug {
+sub check_email_fields {
my ($fields) = @_;
- debug_print('Posting a new bug...');
-
- my $user = Bugzilla->user;
my ($retval, $non_conclusive_fields) =
Bugzilla::User::match_field({
'assigned_to' => { 'type' => 'single' },
'qa_contact' => { 'type' => 'single' },
- 'cc' => { 'type' => 'multi' }
+ 'cc' => { 'type' => 'multi' },
+ 'newcc' => { 'type' => 'multi' }
}, $fields, MATCH_SKIP_CONFIRM);
if ($retval != USER_MATCH_SUCCESS) {
ThrowUserError('user_match_too_many', {fields => $non_conclusive_fields});
}
+}
+
+sub post_bug {
+ my ($fields) = @_;
+ debug_print('Posting a new bug...');
+
+ my $user = Bugzilla->user;
+
+ check_email_fields($fields);
my $bug = Bugzilla::Bug->create($fields);
debug_print("Created bug " . $bug->id);
@@ -214,6 +221,8 @@ sub process_bug {
$fields{'removecc'} = 1;
}
+ check_email_fields(\%fields);
+
my $cgi = Bugzilla->cgi;
foreach my $field (keys %fields) {
$cgi->param(-name => $field, -value => $fields{$field});
diff --git a/template/en/default/bug/edit.html.tmpl b/template/en/default/bug/edit.html.tmpl
index 3a154b557..ccec86449 100644
--- a/template/en/default/bug/edit.html.tmpl
+++ b/template/en/default/bug/edit.html.tmpl
@@ -531,15 +531,11 @@
[%############################################################################%]
[% BLOCK section_url_keyword_whiteboard %]
<tr>
- <td class="field_label">
- <label for="bug_file_loc" accesskey="u"><b>
- [% IF is_safe_url(bug.bug_file_loc) %]
- <a href="[% bug.bug_file_loc FILTER html %]"><u>U</u>RL</a>
- [% ELSE %]
- <u>U</u>RL
- [% END %]
- [%%]</b></label>:
- </td>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.bug_file_loc
+ editable = 1
+ accesskey = "u"
+ %]
<td>
[% IF bug.check_can_change_field("bug_file_loc", 0, 1) %]
<span id="bz_url_edit_container" class="bz_default_hidden">
diff --git a/template/en/default/bug/field-label.html.tmpl b/template/en/default/bug/field-label.html.tmpl
index fe3bed75b..ecb49318e 100644
--- a/template/en/default/bug/field-label.html.tmpl
+++ b/template/en/default/bug/field-label.html.tmpl
@@ -24,6 +24,7 @@
# hidden: True if the field label should start hidden.
# rowspan: a "rowspan" value for the label's <th>.
# tag_name: the tag to use to surround the label
+ # accesskey: access key for the label
#%]
[% DEFAULT tag_name = "th" %]
@@ -33,7 +34,7 @@
[% IF rowspan %] rowspan="[% rowspan FILTER html %]"[% END %]>
[% IF editable %]
- <label for="[% field.name FILTER html %]">
+ <label for="[% field.name FILTER html %]"[% IF accesskey %] accesskey="[% accesskey FILTER html %]"[% END %]>
[% END %]
<a