Index: buglist.cgi
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/buglist.cgi,v
retrieving revision 1.195
diff -u -b -B -r1.195 buglist.cgi
--- buglist.cgi 22 Sep 2002 17:14:50 -0000 1.195
+++ buglist.cgi 26 Sep 2002 15:23:37 -0000
@@ -52,6 +52,7 @@
@legal_severity
@settable_resolution
@target_milestone
+ @legal_customfield
$unconfirmedstate
$userid
@versions);
@@ -72,6 +73,9 @@
# Whether or not the user wants to change multiple bugs.
my $dotweak = $::FORM{'tweak'} ? 1 : 0;
+# needed for user logins, and custom fields.
+GetVersionTable();
+
# Log the user in
if ($dotweak) {
confirm_login();
@@ -80,7 +84,6 @@
multiple bugs.");
exit;
}
- GetVersionTable();
}
else {
quietly_check_login();
@@ -373,6 +376,7 @@
# requests "all" columns.
my $columns = {};
+my $name = "";
sub DefineColumn {
my ($id, $name, $title) = @_;
$columns->{$id} = { 'name' => $name , 'title' => $title };
@@ -401,6 +405,9 @@
DefineColumn("votes" , "bugs.votes" , "Votes" );
DefineColumn("keywords" , "bugs.keywords" , "Keywords" );
+foreach $name (keys %::legal_customfields) {
+ DefineColumn($name, "bugs_customfields.value", $name);
+}
################################################################################
# Display Column Determination
@@ -409,6 +416,7 @@
# Determine the columns that will be displayed in the bug list via the
# columnlist CGI parameter, the user's preferences, or the default.
my @displaycolumns = ();
+my @custom_columns = ();
if (defined $::FORM{'columnlist'}) {
if ($::FORM{'columnlist'} eq "all") {
# If the value of the CGI parameter is "all", display all columns,
@@ -428,6 +436,23 @@
@displaycolumns = @::default_column_list;
}
+# remove custom columns from @displaycolumns and add them to @custom_columns
+my @displaycolumns_tmp;
+
+foreach my $c (@displaycolumns) {
+ # this allows spaces in customfields for the space-delimited COLUMNLIST cookie.
+ $c = url_decode($c);
+
+ if (exists $::legal_customfields{$c}) {
+ push(@custom_columns, $c);
+ }
+ else {
+ push (@displaycolumns_tmp, $c);
+ }
+}
+
+@displaycolumns = @displaycolumns_tmp;
+
# Weed out columns that don't actually exist to prevent the user
# from hacking their column list cookie to grab data to which they
# should not have access. Detaint the data along the way.
@@ -477,6 +502,9 @@
# Convert the list of columns being selected into a list of column names.
my @selectnames = map($columns->{$_}->{'name'}, @selectcolumns);
+# Add the customfields columns to the displayed columns
+push (@displaycolumns, @custom_columns);
+
# Generate the basic SQL query that will be used to generate the bug list.
my $search = new Bugzilla::Search('fields' => \@selectnames,
'url' => $::buffer);
@@ -544,6 +572,10 @@
};
# DEFAULT
$order = "bugs.bug_status, bugs.priority, map_assigned_to.login_name, bugs.bug_id";
+
+ };
+ if (@custom_columns > 1) {
+ $order =~ s/bugs_customfields.value,//g;
}
$db_order = $order; # Copy $order into $db_order for use with SQL query
@@ -633,6 +665,32 @@
push(@bugs, $bug);
}
+# Get the data for the customfields. I generate the SQL in a bit of a weird way
+# to get my OR relationship straight. May need tuning by an SQL guru.
+
+if (@bugs) {
+ my $customSQLquery = "";
+ foreach (map($_->{id}, @bugs)) {
+ if ($customSQLquery) {
+ $customSQLquery .=" OR ";
+ }
+ $customSQLquery .= "bugs_customfields.bug_id = $_"
+ }
+ $customSQLquery = "SELECT bugs_customfields.bug_id, customfields.name, bugs_customfields.value FROM bugs_customfields, customfields WHERE bugs_customfields.cf_id = customfields.id AND value != \"\" AND ($customSQLquery)";
+ SendSQL($customSQLquery);
+
+ # somewhat messy, re-attach the customfields results to the bugs listing.
+ my $bug;
+ while (my @row = FetchSQLData()) {
+ foreach $bug (@bugs) {
+ if ($$bug{'id'} == $row[0]) {
+ $$bug{$row[1]}=$row[2];
+ }
+ }
+ }
+}
+
+
# Switch back from the shadow database to the regular database so PutFooter()
# can determine the current user even if the "logincookies" table is corrupted
# in the shadow database.
Index: checksetup.pl
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/checksetup.pl,v
retrieving revision 1.192
diff -u -b -B -r1.192 checksetup.pl
--- checksetup.pl 25 Sep 2002 07:11:33 -0000 1.192
+++ checksetup.pl 26 Sep 2002 15:23:38 -0000
@@ -1665,6 +1665,42 @@
print "\nISAM->MyISAM table conversion done.\n\n";
}
+# Table that defines custom fields
+#
+$table{'customfields'} =
+ "id mediumint(9) default '0' not null auto_increment,
+ name varchar(64) default '' not null,
+ type enum('any','single','multi'),
+ valid_exp mediumtext not null default '',
+ default_value mediumtext not null default '',
+ mandatory tinyint not null default 0,
+ KEY id (id),
+ index(name)";
+
+#
+# Product to CustomField join
+#
+$table{'products_customfields'} =
+ "product varchar(64) default '' not null,
+ cf_id mediumint(9) default '0' not null,
+
+ index(product),
+ index(cf_id)";
+
+
+#
+# Bug to CustomField join
+#
+$table{'bugs_customfields'} =
+ "bug_id mediumint(9) default '0' not null,
+ cf_id mediumint(9) default '0' not null,
+ value mediumtext,
+
+ index(bug_id, cf_id),
+ index(cf_id, bug_id)";
+
+
+
# Get a list of the existing tables (if any) in the database
my @tables = map { $_ =~ s/.*\.//; $_ } $dbh->tables;
@@ -2815,6 +2851,13 @@
# Add a field for the attachment ID to the bugs_activity table, so installations
# using the attachment manager can record changes to attachments.
AddField("bugs_activity", "attach_id", "mediumint null");
+
+if (&TableExists('customfields')) {
+ RenameField ('customfields', 'valexp', 'valid_exp');
+ AddField('customfields', 'default_value', "mediumtext not null default ''");
+ AddField('customfields', 'mandatory', 'tinyint not null default 0');
+}
+
# 2002-02-04 bbaetz@student.usyd.edu.au bug 95732
# Remove logincookies.cryptpassword, and delete entries which become
Index: colchange.cgi
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/colchange.cgi,v
retrieving revision 1.30
diff -u -b -B -r1.30 colchange.cgi
--- colchange.cgi 26 Aug 2002 06:16:53 -0000 1.30
+++ colchange.cgi 26 Sep 2002 15:23:38 -0000
@@ -60,6 +60,11 @@
push(@masterlist, ("summary", "summaryfull"));
+SendSQL("select name from customfields order by name");
+while (my @row = FetchSQLData()) {
+ push(@masterlist, $row[0]);
+}
+
$vars->{'masterlist'} = \@masterlist;
my @collist;
@@ -70,7 +75,8 @@
} else {
foreach my $i (@masterlist) {
if (defined $::FORM{"column_$i"}) {
- push @collist, $i;
+ # this allows spaces in customfields for the space-delimited COLUMNLIST cookie.
+ push @collist, url_quote($i);
}
}
if (exists $::FORM{'splitheader'}) {
@@ -92,7 +98,9 @@
}
if (defined $::COOKIE{'COLUMNLIST'}) {
- @collist = split(/ /, $::COOKIE{'COLUMNLIST'});
+ foreach(split(/ /, ($::COOKIE{'COLUMNLIST'}))) {
+ push @collist, url_decode($_);
+ }
} else {
@collist = @::default_column_list;
}
Index: long_list.cgi
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/long_list.cgi,v
retrieving revision 1.31
diff -u -b -B -r1.31 long_list.cgi
--- long_list.cgi 22 Sep 2002 17:14:54 -0000 1.31
+++ long_list.cgi 26 Sep 2002 15:23:38 -0000
@@ -74,6 +74,7 @@
my %bug;
my @row = FetchSQLData();
+ my @cfields;
foreach my $field ("bug_id", "product", "version", "rep_platform",
"op_sys", "bug_status", "resolution", "priority",
@@ -84,6 +85,18 @@
$bug{$field} = shift @row;
}
+ # Read all the custom fields value for this bug
+ SendSQL("select name, value from customfields, bugs_customfields where bug_id=$bug_id and id=cf_id");
+
+ # Weird but the only way I found to make the templates work (see show-multiple.html.tmpl)
+ while (@row = FetchSQLData()) {
+ $bug{$row[0]} = $row[1];
+ my $name = shift @row;
+ push (@cfields,$name);
+ }
+
+ $bug{'customfield'} = \@cfields;
+
if ($bug{'bug_id'}) {
$bug{'comments'} = GetComments($bug{'bug_id'});
$bug{'qa_contact'} = $bug{'qa_contact'} > 0 ?
Index: post_bug.cgi
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/post_bug.cgi,v
retrieving revision 1.67
diff -u -b -B -r1.67 post_bug.cgi
--- post_bug.cgi 23 Sep 2002 07:12:11 -0000 1.67
+++ post_bug.cgi 26 Sep 2002 15:23:38 -0000
@@ -43,6 +43,8 @@
$zz = @::legal_product;
$zz = @::legal_severity;
$zz = %::target_milestone;
+ $zz = %::customfields;
+ $zz = %::legal_customfields;
}
# Use global template variables.
@@ -92,6 +94,8 @@
umask 0;
+GetVersionTable();
+
# Some sanity checking
if(Param("usebuggroupsentry") && GroupExists($product)) {
if(!UserInGroup($product)) {
@@ -165,8 +169,6 @@
$::FORM{'priority'} = Param('defaultpriority');
}
-GetVersionTable();
-
# Some more sanity checking
CheckFormField(\%::FORM, 'product', \@::legal_product);
CheckFormField(\%::FORM, 'rep_platform', \@::legal_platform);
@@ -283,6 +285,13 @@
}
+for my $cfname (@{$::customfields{$::FORM{'product'}}}) {
+ my ($type, $valid_exp, $id, $mandatory, $default_value) =
+ @{$::legal_customfields{$cfname}};
+}
+
+
+
# Lock tables before inserting records for the new bug into the database
# if we are using a shadow database to prevent shadow database corruption
# when two bugs get created at the same time.
@@ -308,6 +317,40 @@
# Insert the cclist into the database
foreach my $ccid (keys(%ccids)) {
SendSQL("INSERT INTO cc (bug_id, who) VALUES ($id, $ccid)");
+}
+
+# Handle custom fields
+for (@{$::customfields{$product}}) {
+ my $new_value;
+ my $name = $_;
+ SendSQL("select id, type, default_value from customfields where name='$_'");
+ my ($cf_id,$cf_type, $cf_default) = FetchSQLData();
+
+ # if no value is given use the default value.
+ if ( !defined $::FORM{$_} ) {
+ # Should be faster with legal_customfields
+ $new_value = $cf_default;
+ }
+ else {
+ if ( $cf_type eq "multi" ) {
+ my %F;
+ my %M;
+ ParseUrlString($::buffer, \%F, \%M);
+ my $i;
+ $i=0;
+ while ( @{$M{$_}}[$i] )
+ {
+ if ( $new_value ) { $new_value .= "|"; };
+ $new_value .= @{$M{$name}}[$i];
+ $i++;
+ }
+ }
+ else
+ {
+ $new_value = $::FORM{$_};
+ }
+ }
+ SendSQL("insert into bugs_customfields values($id, $cf_id, " . SqlQuote($new_value) . ")");
}
if (UserInGroup("editbugs")) {
Index: process_bug.cgi
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/process_bug.cgi,v
retrieving revision 1.148
diff -u -b -B -r1.148 process_bug.cgi
--- process_bug.cgi 23 Sep 2002 07:12:12 -0000 1.148
+++ process_bug.cgi 26 Sep 2002 15:23:38 -0000
@@ -47,6 +47,7 @@
%settable_resolution
%target_milestone
%legal_severity
+ %customfields
$next_bug);
ConnectToDatabase();
@@ -912,6 +913,11 @@
}
+for my $cfname (@{$::customfields{$::FORM{'product'}}}) {
+ my ($type, $valid_exp, $id, $mandatory, $default_value) =
+ @{$::legal_customfields{$cfname}};
+}
+
my @keywordlist;
my %keywordseen;
@@ -1543,6 +1549,53 @@
|| ThrowTemplateError($template->error());
}
+
+ #Read all the custom field value for this bug
+ SendSQL("select name, value, id from customfields, bugs_customfields where bug_id=$id and id=cf_id");
+
+ my (%cfbug, @row);
+ while (@row = FetchSQLData()) {
+ $cfbug{$row[0]} = [$row[1], $row[2]];
+ }
+
+ foreach (@{$::customfields{$::FORM{'product'}}}) {
+ # Check if values changed
+ if ($cfbug{$_}[0] ne $::FORM{$_}) {
+ # Got a change
+ # Have to check it - this happens when bug is confirmed after adding a field
+ if ( $cfbug{$_}[1] ) {
+ SendSQL( "select type, name from customfields where id = $cfbug{$_}[1]" );
+ my ($type,$name) = FetchSQLData();
+ my $new_value;
+
+ if ( $type eq "multi" ) {
+ my %F;
+ my %M;
+ ParseUrlString($::buffer, \%F, \%M);
+ my $i;
+ $i=0;
+ while ( @{$M{$name}}[$i] ) {
+ if ( $new_value ) { $new_value .= "|"; };
+ $new_value .= @{$M{$name}}[$i];
+ $i++;
+ }
+ }
+ else {
+ $new_value = $::FORM{$_};
+ }
+
+ if ($new_value ne $cfbug{$_}[0]){
+ my $qstr = "UPDATE bugs_customfields SET value = " .SqlQuote($new_value) . " WHERE cf_id=$cfbug{$_}[1] and bug_id=$id";
+ SendSQL($qstr);
+
+ my $fid = GetFieldID($_);
+ $qstr = "INSERT INTO bugs_activity (bug_id,who,bug_when,fieldid,removed,added)" .
+ " values ($id,$whoid," .SqlQuote($timestamp) . ",$fid, " . SqlQuote($cfbug{$_}[0]) ." ," . SqlQuote($::FORM{$_}) . " )";
+ SendSQL($qstr);
+ }
+ }
+ }
+ }
}
# Show next bug, if it exists.
Index: bug_form.pl
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/bug_form.pl,v
retrieving revision 1.104
diff -u -b -B -r1.104 bug_form.pl
--- bug_form.pl 22 Sep 2002 17:14:50 -0000 1.104
+++ bug_form.pl 26 Sep 2002 15:23:38 -0000
@@ -28,6 +28,7 @@
# Use the Attachment module to display attachments for the bug.
use Attachment;
+my @cfields;
sub show_bug {
# Shut up misguided -w warnings about "used only once". For some reason,
# "use vars" chokes on me when I try it here.
@@ -121,6 +122,77 @@
$bug{$field} = defined($value) ? $value : "";
}
+
+ # Support for customfields.
+ SendSQL("select name, value from customfields, bugs_customfields where bug_id=$id and id=cf_id");
+
+ while (@row = FetchSQLData())
+ {
+ $bug{$row[0]} = $row[1];
+ }
+
+ for (@{$::customfields{$bug{'product'}}}) {
+ # print STDERR "*** '$_'"; print STDERR " value: $bug{$_} *** \n";
+ # print "bug id: $id value : $bug{$_}
";
+
+ my %cbug;
+
+ $cbug{'name'} = $_;
+ $cbug{'type'} = $::legal_customfields{$_}[0];
+ $cbug{'default'} = $::legal_customfields{$_}[4];
+
+ if ($cbug{'type'} eq "any") {
+ if ($bug{$_} eq '') {
+ $cbug{'values'} = $cbug{'default'};
+ }
+ else {
+ $cbug{'values'} = $bug{$_};
+ }
+ }
+ else {
+ $cbug{'values'} = [split('\|',$::legal_customfields{$_}[1])];
+
+ if ($cbug{'type'} eq "single") {
+ if ($bug{$_} eq '') {
+ $cbug{'selectedvalues'} = $cbug{'default'};
+ }
+ else {
+ $cbug{'selectedvalues'} = $bug{$_};
+ }
+ }
+
+ elsif ($cbug{'type'} eq "multi") {
+ if ($bug{$_} eq '') {
+ $cbug{'selectedvalues'} = [split('\|', $cbug{'default'})];
+ }
+ else {
+ $cbug{'selectedvalues'} = [split('\|',$bug{$_})];
+ }
+ }
+ }
+ push @cfields, \%cbug;
+
+ if ( $bug{$_} eq "" )
+ {
+ # Custom field has no value. Maybe does not exist for bug?
+ # This can happen if customfield was assigned to product after bug was reported
+ SendSQL("select id from customfields where name='$_'");
+ my ($cf_id) = FetchSQLData();
+ if ( $cf_id )
+ {
+ SendSQL("select count(bug_id) from bugs_customfields where bug_id=$id and cf_id = $cf_id");
+ my ($bug_count) = FetchSQLData();
+ if ( $bug_count == 0 )
+ {
+ # print "This will be added here
";
+ SendSQL( "insert into bugs_customfields (bug_id, cf_id, value) VALUES ($id, $cf_id, '".$bug{$_}."')");
+ }
+ }
+ }
+ }
+
+
+
# General arrays of info about the database state
GetVersionTable();
@@ -158,6 +230,7 @@
@prodlist = sort @prodlist;
}
+ $vars->{'customfield'} = \@cfields;
$vars->{'product'} = \@prodlist;
$vars->{'rep_platform'} = \@::legal_platform;
$vars->{'priority'} = \@::legal_priority;
Index: enter_bug.cgi
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/enter_bug.cgi,v
retrieving revision 1.73
diff -u -b -B -r1.73 enter_bug.cgi
--- enter_bug.cgi 22 Sep 2002 17:14:53 -0000 1.73
+++ enter_bug.cgi 26 Sep 2002 15:23:38 -0000
@@ -48,6 +48,8 @@
@legal_platform
@legal_priority
@legal_severity
+ @customfields
+ @legal_customfields
$userid
%MFORM
%versions
@@ -277,7 +279,41 @@
}
my %default;
+my @cfields;
+
+# custom fields
+for (@{$::customfields{$product}}) {
+
+ my %cbug;
+
+ $cbug{'name'} = $_;
+ $cbug{'type'} = $::legal_customfields{$_}[0];
+
+ if ($cbug{'type'} eq "any") {
+ $cbug{'values'}=$::legal_customfields{$_}[1];
+ }
+ else {
+ $cbug{'values'} = [split('\|',$::legal_customfields{$_}[1])];
+ }
+ $cbug{'mandatory'} = $::legal_customfields{$_}[3];
+ $cbug{'default'} = $::legal_customfields{$_}[4];
+
+#To use default values. Uncomment the following lines to use this feature.
+
+# if ($cbug{'type'} eq "single") {
+# $cbug{'selectedvalues'} = $cbug{'default'};
+# # print "value : $cbug{'val_selected'}
";
+# }
+# elsif ($cbug{'type'} eq "multi") {
+# $cbug{'selectedvalues'} = [split('\|', $cbug{'default'})];
+# }
+
+ push @cfields, \%cbug;
+}
+
+
+$vars->{'customfield'} = \@cfields;
$vars->{'component_'} = \@components;
$default{'component_'} = formvalue('component');
Index: globals.pl
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/globals.pl,v
retrieving revision 1.204
diff -u -b -B -r1.204 globals.pl
--- globals.pl 25 Sep 2002 07:11:32 -0000 1.204
+++ globals.pl 26 Sep 2002 15:23:39 -0000
@@ -355,6 +355,30 @@
$carray{$c} = 1;
}
+ # Adding custom field support
+ SendSQL("select name, product from customfields, products_customfields where id=cf_id order by id");
+ while (@line = FetchSQLData()) {
+ my ($n, $p) = (@line);
+ if (!defined $::customfields{$p}) {
+ $::customfields{$p} = [];
+ }
+ my $ref = $::customfields{$p};
+ push @$ref, $n;
+ }
+
+ # type should indicate what's legal (any,single,multi)
+ # this is good for type = single and multi (for now ...)
+ SendSQL("select name, type, valid_exp, id, mandatory, default_value" .
+ " from customfields order by id");
+ while (@line = FetchSQLData()) {
+ my ($n, $t, $ve, $id, $m, $d) = (@line);
+ if (!defined $::legal_customfields{$n}) {
+ $::legal_customfields{$n} = [];
+ }
+ my $ref = $::legal_customfields{$n};
+ push @$ref, $t, $ve, $id, $m, $d;
+ }
+
my $dotargetmilestone = 1; # This used to check the param, but there's
# enough code that wants to pretend we're using
# target milestones, even if they don't get
@@ -434,6 +458,14 @@
['*::legal_versions', '*::components']);
@::legal_components = sort {uc($a) cmp uc($b)} keys(%carray);
+ foreach my $i (@list) {
+ if (!defined $::customfields{$i}) {
+ $::customfields{$i} = [];
+ }
+ }
+ print FID Data::Dumper->Dump([\%::legal_customfields, \%::customfields],
+ ['*::legal_customfields', '*::customfields']);
+
print FID Data::Dumper->Dump([\@::legal_components, \@::legal_product,
\@::legal_priority, \@::legal_severity,
\@::legal_platform, \@::legal_opsys,
Index: template/en/default/global/useful-links.html.tmpl
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/template/en/default/global/useful-links.html.tmpl,v
retrieving revision 1.10
diff -u -b -B -r1.10 useful-links.html.tmpl
--- template/en/default/global/useful-links.html.tmpl 22 Sep 2002 17:15:13 -0000 1.10
+++ template/en/default/global/useful-links.html.tmpl 26 Sep 2002 15:23:39 -0000
@@ -74,6 +74,8 @@
IF user.groups.creategroups %]
[% ', keywords'
IF user.groups.editkeywords %]
+ [% ", Customfields"
+ IF user.groups.editkeywords %]
[% ' | Sanity check'
IF user.groups.tweakparams %]
Index: template/en/default/bug/edit.html.tmpl
===================================================================
RCS file: /cvsroot/mozilla/webtools/bugzilla/template/en/default/bug/edit.html.tmpl,v
retrieving revision 1.19
diff -u -b -B -r1.19 edit.html.tmpl
--- template/en/default/bug/edit.html.tmpl 19 Aug 2002 21:17:28 -0000 1.19
+++ template/en/default/bug/edit.html.tmpl 26 Sep 2002 15:23:39 -0000
@@ -171,6 +171,58 @@
[% PROCESS select selname = "bug_severity" accesskey => "e" %]
+
+
+
+