diff options
-rw-r--r-- | Attachment.pm | 26 | ||||
-rw-r--r-- | Bugzilla/Attachment.pm | 26 | ||||
-rw-r--r-- | bug_form.pl | 825 | ||||
-rwxr-xr-x | process_bug.cgi | 89 | ||||
-rwxr-xr-x | show_bug.cgi | 29 | ||||
-rw-r--r-- | template/default/show/choose_bug.html.tmpl | 35 | ||||
-rw-r--r-- | template/default/show/navigate.html.tmpl | 53 | ||||
-rw-r--r-- | template/default/show/show_bug.html.tmpl | 527 |
8 files changed, 937 insertions, 673 deletions
diff --git a/Attachment.pm b/Attachment.pm index 7416fd589..23e634276 100644 --- a/Attachment.pm +++ b/Attachment.pm @@ -27,16 +27,8 @@ use diagnostics; use strict; -use vars qw( - $template - $vars -); - package Attachment; -my $template = $::template; -my $vars = $::vars; - # This module requires that its caller have said "require CGI.pl" to import # relevant functions from that script and its companion globals.pl. @@ -44,11 +36,11 @@ my $vars = $::vars; # Functions ############################################################################ -sub list +sub query { - # Displays a table of attachments for a given bug along with links for - # viewing, editing, or making requests for each attachment. - + # Retrieves and returns an array of attachment records for a given bug. + # This data should be given to attachment/list.atml in an + # "attachments" variable. my ($bugid) = @_; my $in_editbugs = &::UserInGroup("editbugs"); @@ -98,14 +90,8 @@ sub list $in_editbugs); push @attachments, \%a; } - - $vars->{'bugid'} = $bugid; - $vars->{'attachments'} = \@attachments; - - $template->process("attachment/list.atml", $vars) - || &::DisplayError("Template process failed: " . $template->error()) - && exit; - + + return \@attachments; } 1; diff --git a/Bugzilla/Attachment.pm b/Bugzilla/Attachment.pm index 7416fd589..23e634276 100644 --- a/Bugzilla/Attachment.pm +++ b/Bugzilla/Attachment.pm @@ -27,16 +27,8 @@ use diagnostics; use strict; -use vars qw( - $template - $vars -); - package Attachment; -my $template = $::template; -my $vars = $::vars; - # This module requires that its caller have said "require CGI.pl" to import # relevant functions from that script and its companion globals.pl. @@ -44,11 +36,11 @@ my $vars = $::vars; # Functions ############################################################################ -sub list +sub query { - # Displays a table of attachments for a given bug along with links for - # viewing, editing, or making requests for each attachment. - + # Retrieves and returns an array of attachment records for a given bug. + # This data should be given to attachment/list.atml in an + # "attachments" variable. my ($bugid) = @_; my $in_editbugs = &::UserInGroup("editbugs"); @@ -98,14 +90,8 @@ sub list $in_editbugs); push @attachments, \%a; } - - $vars->{'bugid'} = $bugid; - $vars->{'attachments'} = \@attachments; - - $template->process("attachment/list.atml", $vars) - || &::DisplayError("Template process failed: " . $template->error()) - && exit; - + + return \@attachments; } 1; diff --git a/bug_form.pl b/bug_form.pl index 6d52011c7..e51107bfb 100644 --- a/bug_form.pl +++ b/bug_form.pl @@ -28,604 +28,293 @@ use RelationSet; # Use the Attachment module to display attachments for the bug. use Attachment; -# Shut up misguided -w warnings about "used only once". For some reason, -# "use vars" chokes on me when I try it here. - -sub bug_form_pl_sillyness { - my $zz; - $zz = %::FORM; - $zz = %::components; - $zz = %::proddesc; - $zz = %::prodmaxvotes; - $zz = %::versions; - $zz = @::enterable_products; - $zz = @::legal_keywords; - $zz = @::legal_opsys; - $zz = @::legal_platform; - $zz = @::legal_priority; - $zz = @::settable_resolution; - $zz = @::legal_severity; - $zz = %::target_milestone; -} - -my $loginok = quietly_check_login(); - -my $id = $::FORM{'id'}; - -my $query = " -select - bugs.bug_id, - product, - version, - rep_platform, - op_sys, - bug_status, - resolution, - priority, - bug_severity, - component, - assigned_to, - reporter, - bug_file_loc, - short_desc, - target_milestone, - qa_contact, - status_whiteboard, - date_format(creation_ts,'%Y-%m-%d %H:%i'), - groupset, - delta_ts, - sum(votes.count) -from bugs left join votes using(bug_id) -where bugs.bug_id = $id -group by bugs.bug_id"; - -SendSQL($query); -my %bug; -my @row; -@row = FetchSQLData(); -my $count = 0; -foreach my $field ("bug_id", "product", "version", "rep_platform", - "op_sys", "bug_status", "resolution", "priority", - "bug_severity", "component", "assigned_to", "reporter", - "bug_file_loc", "short_desc", "target_milestone", - "qa_contact", "status_whiteboard", "creation_ts", - "groupset", "delta_ts", "votes") { - $bug{$field} = shift @row; - if (!defined $bug{$field}) { - $bug{$field} = ""; +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. + sub bug_form_pl_sillyness { + my $zz; + $zz = %::FORM; + $zz = %::proddesc; + $zz = %::prodmaxvotes; + $zz = @::enterable_products; + $zz = @::settable_resolution; + $zz = $::unconfirmedstate; + $zz = $::milestoneurl; + $zz = $::template; + $zz = $::vars; + $zz = @::legal_priority; + $zz = @::legal_platform; + $zz = @::legal_severity; + $zz = @::legal_bug_status; + $zz = @::target_milestone; + $zz = @::components; + $zz = @::legal_keywords; + $zz = @::versions; + $zz = @::legal_opsys; } - $count++; -} - -my $assignedtoid = $bug{'assigned_to'}; -my $reporterid = $bug{'reporter'}; -my $qacontactid = $bug{'qa_contact'}; - -$bug{'assigned_to_email'} = DBID_to_name($assignedtoid); -$bug{'assigned_to'} = DBID_to_real_or_loginname($bug{'assigned_to'}); -$bug{'reporter'} = DBID_to_real_or_loginname($bug{'reporter'}); - -print qq{<FORM NAME="changeform" METHOD="POST" ACTION="process_bug.cgi">\n}; - -# foreach my $i (sort(keys(%bug))) { -# my $q = value_quote($bug{$i}); -# print qq{<INPUT TYPE="HIDDEN" NAME="orig-$i" VALUE="$q">\n}; -# } - -$bug{'long_desc'} = GetLongDescriptionAsHTML($id); -my $longdesclength = length($bug{'long_desc'}); - -GetVersionTable(); - - -# -# These should be read from the database ... -# - -my $platform_popup = make_options(\@::legal_platform, $bug{'rep_platform'}); -my $priority_popup = make_options(\@::legal_priority, $bug{'priority'}); -my $sev_popup = make_options(\@::legal_severity, $bug{'bug_severity'}); - - -my $component_popup = make_options($::components{$bug{'product'}}, - $bug{'component'}); - -my $ccSet = new RelationSet; -$ccSet->mergeFromDB("select who from cc where bug_id=$id"); -my @ccList = $ccSet->toArrayOfStrings(); -my $cc_element = "<INPUT TYPE=HIDDEN NAME=cc VALUE=\"\">"; -if (scalar(@ccList) > 0) { - $cc_element = "<SELECT NAME=cc MULTIPLE SIZE=5>\n"; - foreach my $ccName ( @ccList ) { - $cc_element .= "<OPTION VALUE=\"$ccName\">$ccName\n"; - } - $cc_element .= "</SELECT><BR>\n" . - "<INPUT TYPE=CHECKBOX NAME=removecc>Remove selected CCs<br>\n"; -} - -my $URL = value_quote($bug{'bug_file_loc'}); - -if (defined $URL && $URL ne "none" && $URL ne "NULL" && $URL ne "") { - $URL = "<B><A HREF=\"$URL\">URL:</A></B>"; -} else { - $URL = "<B>URL:</B>"; -} - -# -# Make a list of products the user has access to -# - -my (@prodlist, $product_popup); -my $seen_currProd = 0; - -foreach my $p (@::enterable_products) { - if ($p eq $bug{'product'}) { - # if it's the product the bug is already in, it's ALWAYS in - # the popup, period, whether the user can see it or not, and - # regardless of the disallownew setting. - $seen_currProd = 1; - push(@prodlist, $p); - next; + # Use templates + my $template = $::template; + my $vars = $::vars; + + $vars->{'GetBugLink'} = \&GetBugLink; + $vars->{'quoteUrls'} = \"eUrls, + $vars->{'lsearch'} = \&lsearch, + $vars->{'header_done'} = (@_), + + quietly_check_login(); + + my $id = $::FORM{'id'}; + + if (!defined($id)) { + $template->process("show/choose_bug.html.tmpl", $vars) + || DisplayError("Template process failed: " . $template->error()); + exit; } - if(Param("usebuggroupsentry") - && GroupExists($p) - && !UserInGroup($p)) + + my %user; + my %bug; + + # Populate the bug hash with the info we get directly from the DB. + my $query = " + SELECT bugs.bug_id, product, version, rep_platform, + op_sys, bug_status, resolution, priority, + bug_severity, component, assigned_to, reporter, + bug_file_loc, short_desc, target_milestone, + qa_contact, status_whiteboard, + date_format(creation_ts,'%Y-%m-%d %H:%i'), + groupset, delta_ts, sum(votes.count) + FROM bugs LEFT JOIN votes USING(bug_id) + WHERE bugs.bug_id = $id + GROUP BY bugs.bug_id"; + + SendSQL($query); + + my $value; + my @row = FetchSQLData(); + foreach my $field ("bug_id", "product", "version", "rep_platform", + "op_sys", "bug_status", "resolution", "priority", + "bug_severity", "component", "assigned_to", "reporter", + "bug_file_loc", "short_desc", "target_milestone", + "qa_contact", "status_whiteboard", "creation_ts", + "groupset", "delta_ts", "votes") { - # If we're using bug groups to restrict entry on products, and - # this product has a bug group, and the user is not in that - # group, we don't want to include that product in this list. - next; + $value = shift(@row); + $bug{$field} = defined($value) ? $value : ""; } - push(@prodlist, $p); -} - -# The current product is part of the popup, even if new bugs are no longer -# allowed for that product -if (!$seen_currProd) { - push (@prodlist, $bug{'product'}); - @prodlist = sort @prodlist; -} -# If the user has access to multiple products, display a popup, otherwise -# display the current product. + # General arrays of info about the database state + GetVersionTable(); + + # Fiddle the product list. + my $seen_curr_prod; + my @prodlist; + + foreach my $product (@::enterable_products) { + if ($product eq $bug{'product'}) { + # if it's the product the bug is already in, it's ALWAYS in + # the popup, period, whether the user can see it or not, and + # regardless of the disallownew setting. + $seen_curr_prod = 1; + push(@prodlist, $product); + next; + } -if (1 < @prodlist) { - $product_popup = "<SELECT NAME=product>" . - make_options(\@prodlist, $bug{'product'}) . - "</SELECT>"; -} -else { - $product_popup = $bug{'product'} . - "<INPUT TYPE=\"HIDDEN\" NAME=\"product\" VALUE=\"$bug{'product'}\">"; -} + if (Param("usebuggroupsentry") + && GroupExists($product) + && !UserInGroup($product)) + { + # If we're using bug groups to restrict entry on products, and + # this product has a bug group, and the user is not in that + # group, we don't want to include that product in this list. + next; + } -print " -<INPUT TYPE=HIDDEN NAME=\"delta_ts\" VALUE=\"$bug{'delta_ts'}\"> -<INPUT TYPE=HIDDEN NAME=\"longdesclength\" VALUE=\"$longdesclength\"> -<INPUT TYPE=HIDDEN NAME=\"id\" VALUE=$id> - <TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0><TR> - <TD ALIGN=RIGHT><B>Bug#:</B></TD><TD><A HREF=\"" . Param('urlbase') . "show_bug.cgi?id=$bug{'bug_id'}\">$bug{'bug_id'}</A></TD> - <TD> </TD> - <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html#rep_platform\">Platform:</A></B></TD> - <TD><SELECT NAME=rep_platform>$platform_popup</SELECT></TD> - <TD> </TD> - <TD ALIGN=RIGHT><B>Reporter:</B></TD><TD>$bug{'reporter'}</TD> -</TR><TR> - <TD ALIGN=RIGHT><B>Product:</B></TD> - <TD>$product_popup</TD> - <TD> </TD> - <TD ALIGN=RIGHT><B>OS:</B></TD> - <TD><SELECT NAME=op_sys>" . - make_options(\@::legal_opsys, $bug{'op_sys'}) . - "</SELECT></TD> - <TD> </TD> - <TD ALIGN=RIGHT NOWRAP><b>Add CC:</b></TD> - <TD><INPUT NAME=newcc SIZE=30 VALUE=\"\"></TD> -</TR><TR> - <TD ALIGN=RIGHT><B><A HREF=\"describecomponents.cgi?product=" . - url_quote($bug{'product'}) . "\">Component:</A></B></TD> - <TD><SELECT NAME=component>$component_popup</SELECT></TD> - <TD> </TD> - <TD ALIGN=RIGHT><B>Version:</B></TD> - <TD><SELECT NAME=version>" . - make_options($::versions{$bug{'product'}}, $bug{'version'}) . - "</SELECT></TD> - <TD> </TD> - <TD ROWSPAN=4 ALIGN=RIGHT VALIGN=TOP><B>CC:</B></TD> - <TD ROWSPAN=4 VALIGN=TOP> $cc_element </TD> -</TR><TR> - <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html\">Status:</A></B></TD> - <TD>$bug{'bug_status'}</TD> - <TD> </TD> - <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html#priority\">Priority:</A></B></TD> - <TD><SELECT NAME=priority>$priority_popup</SELECT></TD> - <TD> </TD> -</TR><TR> - <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html\">Resolution:</A></B></TD> - <TD>$bug{'resolution'}</TD> - <TD> </TD> - <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html#severity\">Severity:</A></B></TD> - <TD><SELECT NAME=bug_severity>$sev_popup</SELECT></TD> - <TD> </TD> -</TR><TR> - <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html#assigned_to\">Assigned To: - </A></B></TD> - <TD>$bug{'assigned_to'}</TD> - <TD> </TD>"; - -if (Param("usetargetmilestone")) { - my $url = ""; - if (defined $::milestoneurl{$bug{'product'}}) { - $url = $::milestoneurl{$bug{'product'}}; + push(@prodlist, $product); } - if ($url eq "") { - $url = "notargetmilestone.html"; - } - if ($bug{'target_milestone'} eq "") { - $bug{'target_milestone'} = " "; - } - print " -<TD ALIGN=RIGHT><A href=\"$url\"><B>Target Milestone:</B></A></TD> -<TD><SELECT NAME=target_milestone>" . - make_options($::target_milestone{$bug{'product'}}, - $bug{'target_milestone'}) . - "</SELECT></TD> - <TD> </TD>"; -} else { print "<TD></TD><TD></TD><TD> </TD>"; } - -print " -</TR>"; - -if (Param("useqacontact")) { - my $name = $bug{'qa_contact'} > 0 ? DBID_to_name($bug{'qa_contact'}) : ""; - print " - <TR> - <TD ALIGN=\"RIGHT\"><B>QA Contact:</B> - <TD COLSPAN=7> - <INPUT NAME=qa_contact VALUE=\"" . - value_quote($name) . - "\" SIZE=60></TD> - </TR>"; -} - - -print " - <TR> - <TD ALIGN=\"RIGHT\">$URL - <TD COLSPAN=7> - <INPUT NAME=bug_file_loc VALUE=\"" . value_quote($bug{'bug_file_loc'}) . "\" SIZE=60></TD> - </TR><TR> - <TD ALIGN=\"RIGHT\"><B>Summary:</B> - <TD COLSPAN=7> - <INPUT NAME=short_desc VALUE=\"" . - value_quote($bug{'short_desc'}) . - "\" SIZE=60></TD> - </TR>"; - -if (Param("usestatuswhiteboard")) { - print " - <TR> - <TD ALIGN=\"RIGHT\"><B>Status Whiteboard:</B> - <TD COLSPAN=7> - <INPUT NAME=status_whiteboard VALUE=\"" . - value_quote($bug{'status_whiteboard'}) . - "\" SIZE=60></TD> - </TR>"; -} -if (@::legal_keywords) { - SendSQL("SELECT keyworddefs.name - FROM keyworddefs, keywords - WHERE keywords.bug_id = $id AND keyworddefs.id = keywords.keywordid - ORDER BY keyworddefs.name"); - my @list; - while (MoreSQLData()) { - push(@list, FetchOneColumn()); + # The current product is part of the popup, even if new bugs are no longer + # allowed for that product + if (!$seen_curr_prod) { + push (@prodlist, $bug{'product'}); + @prodlist = sort @prodlist; } - my $value = value_quote(join(', ', @list)); - print qq{ -<TR> -<TD ALIGN=right><B><A HREF="describekeywords.cgi">Keywords:</A></B> -<TD COLSPAN=7><INPUT NAME="keywords" VALUE="$value" SIZE=60></TD> -</TR> -}; -} -print "</TABLE>\n"; + $vars->{'product'} = \@prodlist; + $vars->{'rep_platform'} = \@::legal_platform; + $vars->{'priority'} = \@::legal_priority; + $vars->{'bug_severity'} = \@::legal_severity; + $vars->{'op_sys'} = \@::legal_opsys; + $vars->{'bug_status'} = \@::legal_bug_status; + + # Hack - this array contains "" for some reason. See bug 106589. + shift @::settable_resolution; + $vars->{'resolution'} = \@::settable_resolution; + + $vars->{'component_'} = $::components{$bug{'product'}}; + $vars->{'version'} = $::versions{$bug{'product'}}; + $vars->{'target_milestone'} = $::target_milestone{$bug{'product'}}; + $bug{'milestoneurl'} = $::milestoneurl{$bug{'product'}} || + "notargetmilestone.html"; + + $vars->{'use_votes'} = $::prodmaxvotes{$bug{'product'}}; + + # Add additional, calculated fields to the bug hash + if (@::legal_keywords) { + $vars->{'use_keywords'} = 1; + + SendSQL("SELECT keyworddefs.name + FROM keyworddefs, keywords + WHERE keywords.bug_id = $id + AND keyworddefs.id = keywords.keywordid + ORDER BY keyworddefs.name"); + my @keywords; + while (MoreSQLData()) { + push(@keywords, FetchOneColumn()); + } + + $bug{'keywords'} = \@keywords; + } -# Display attachments for this bug (if any). -&Attachment::list($id); + # Attachments + $bug{'attachments'} = Attachment::query($id); -sub EmitDependList { - my ($desc, $myfield, $targetfield) = (@_); - print "<th align=right>$desc:</th><td>"; + # Dependencies my @list; - SendSQL("select $targetfield from dependencies where - $myfield = $id order by $targetfield"); + SendSQL("SELECT dependson FROM dependencies WHERE + blocked = $id ORDER BY dependson"); while (MoreSQLData()) { - my ($i) = (FetchSQLData()); + my ($i) = FetchSQLData(); push(@list, $i); - print GetBugLink($i, $i); - print " "; - } - print "</td><td><input name=$targetfield value=\"" . - join(',', @list) . "\"></td>\n"; -} - -if (Param("usedependencies")) { - print "<table><tr>\n"; - EmitDependList("Bug $id depends on", "blocked", "dependson"); - print qq{ -<td rowspan=2><a href="showdependencytree.cgi?id=$id">Show dependency tree</a> -}; - if (Param("webdotbase") ne "") { - print qq{ -<br><a href="showdependencygraph.cgi?id=$id">Show dependency graph</a> -}; } - print "</td></tr><tr>"; - EmitDependList("Bug $id blocks", "dependson", "blocked"); - print "</tr></table>\n"; -} -if ($::prodmaxvotes{$bug{'product'}}) { - print qq{ -<table><tr> -<th><a href="votehelp.html">Votes:</a></th> -<td> -$bug{'votes'} -<a href="showvotes.cgi?bug_id=$id">Show votes for this bug</a> -<a href="showvotes.cgi?voteon=$id">Vote for this bug</a> -</td> -</tr></table> -}; -} + $bug{'dependson'} = \@list; -print " -<br> -<B>Additional Comments:</B> -<BR> -<TEXTAREA WRAP=HARD NAME=comment ROWS=10 COLS=80></TEXTAREA><BR>"; - - -if ($::usergroupset ne '0' || $bug{'groupset'} ne '0') { - SendSQL("select bit, name, description, (bit & $bug{'groupset'} != 0), " . - "(bit & $::usergroupset != 0) from groups where isbuggroup != 0 " . - # Include active groups as well as inactive groups to which - # the bug already belongs. This way the bug can be removed - # from an inactive group but can only be added to active ones. - "and ((isactive = 1 and (bit & $::usergroupset != 0)) or " . - "(bit & $bug{'groupset'} != 0)) " . - "order by description"); - # We only print out a header bit for this section if there are any - # results. - my $groupFound = 0; - my $inAllGroups = 1; + my @list2; + SendSQL("SELECT blocked FROM dependencies WHERE + dependson = $id ORDER BY blocked"); while (MoreSQLData()) { - my ($bit, $name, $description, $ison, $ingroup) = (FetchSQLData()); - # For product groups, we only want to display the checkbox if either - # (1) The bit is already set, or - # (2) The user is in the group, but either: - # (a) The group is a product group for the current product, or - # (b) The group name isn't a product name - # This measns that all product groups will be skipped, but non-product - # bug groups will still be displayed. - if($ison || ($ingroup && (($name eq $bug{'product'}) || - (!defined $::proddesc{$name})))) { - if(!$groupFound) { - print "<br><b>Only users in the selected groups can view this bug:</b><br>\n"; - print "<font size=\"-1\">(Unchecking all boxes makes this a public bug.)</font><br><br>\n"; - $groupFound = 1; - } - if(!$ingroup) { - $inAllGroups = 0; - } - # Modifying this to use checkboxes instead - my $checked = $ison ? " CHECKED" : ""; - my $disabled = $ingroup ? "" : " DISABLED=\"disabled\""; - # indent these a bit - print " "; - print "<input type=checkbox name=\"bit-$bit\" value=1$checked$disabled>\n"; - print "$description<br>\n"; - } - } - if (!$inAllGroups) { - print "<b>Only members of a group can change the visibility of a bug for that group</b><br>"; + my ($i) = FetchSQLData(); + push(@list2, $i); } - # If the bug is restricted to a group, display checkboxes that allow - # the user to set whether or not the reporter - # and cc list can see the bug even if they are not members of all - # groups to which the bug is restricted. - if ( $bug{'groupset'} != 0 ) { - # Determine whether or not the bug is always accessible by the reporter, - # QA contact, and/or users on the cc: list. - SendSQL("SELECT reporter_accessible, cclist_accessible - FROM bugs - WHERE bug_id = $id - "); - my ($reporter_accessible, $cclist_accessible) = FetchSQLData(); - - # Convert boolean data about which roles always have access to the bug - # into "checked" attributes for the HTML checkboxes by which users - # set and change these values. - my $reporter_checked = $reporter_accessible ? " checked" : ""; - my $cclist_checked = $cclist_accessible ? " checked" : ""; - - # Display interface for changing the values. - print qq| - <p> - <b>But users in the roles selected below can always view this bug:</b><br> - <small>(The assignee - |; - if (Param('useqacontact')) { - print " and qa contact"; - } - print qq| can always see a bug, and this does not take effect unless the bug is restricted to at least one group.)</small> - </p> - - <p> - <input type="checkbox" name="reporter_accessible" value="1" $reporter_checked>Reporter - <input type="checkbox" name="cclist_accessible" value="1" $cclist_checked>CC List - </p> - |; - } -} - - - - - -print "<br> -<INPUT TYPE=radio NAME=knob VALUE=none CHECKED> - Leave as <b>$bug{'bug_status'} $bug{'resolution'}</b><br>"; - - -# knum is which knob number we're generating, in javascript terms. - -my $knum = 1; - -my $status = $bug{'bug_status'}; - -# In the below, if the person hasn't logged in ($::userid == 0), then -# we treat them as if they can do anything. That's because we don't -# know why they haven't logged in; it may just be because they don't -# use cookies. Display everything as if they have all the permissions -# in the world; their permissions will get checked when they log in -# and actually try to make the change. - -my $canedit = UserInGroup("editbugs") || ($::userid == 0); -my $canconfirm; - -if ($status eq $::unconfirmedstate) { - $canconfirm = UserInGroup("canconfirm") || ($::userid == 0); - if ($canedit || $canconfirm) { - print "<INPUT TYPE=radio NAME=knob VALUE=confirm>"; - print "Confirm bug (change status to <b>NEW</b>)<br>"; - $knum++; - } -} - -my $movers = Param("movers"); -$movers =~ s/\s?,\s?/|/g; -$movers =~ s/@/\@/g; - -if ($canedit || $::userid == $assignedtoid || - $::userid == $reporterid || $::userid == $qacontactid) { - if (IsOpenedState($status)) { - if ($status ne "ASSIGNED") { - print "<INPUT TYPE=radio NAME=knob VALUE=accept>"; - my $extra = ""; - if ($status eq $::unconfirmedstate && ($canconfirm || $canedit)) { - $extra = "confirm bug, "; + $bug{'blocked'} = \@list2; + + # Groups + if ($::usergroupset ne '0' || $bug{'groupset'} ne '0') { + my $bug_groupset = $bug{'groupset'}; + + SendSQL("SELECT bit, name, description, (bit & $bug_groupset != 0), + (bit & $::usergroupset != 0) FROM groups + WHERE isbuggroup != 0 " . + # Include active groups as well as inactive groups to which + # the bug already belongs. This way the bug can be removed + # from an inactive group but can only be added to active ones. + "AND ((isactive = 1 AND (bit & $::usergroupset != 0)) OR + (bit & $bug_groupset != 0))"); + + my @groups; + $user{'inallgroups'} = 1; + + while (MoreSQLData()) { + my ($bit, $name, $description, $ison, $ingroup) = FetchSQLData(); + # For product groups, we only want to display the checkbox if either + # (1) The bit is already set, or + # (2) The user is in the group, but either: + # (a) The group is a product group for the current product, or + # (b) The group name isn't a product name + # This means that all product groups will be skipped, but + # non-product bug groups will still be displayed. + if($ison || + ($ingroup && (($name eq $bug{'product'}) || + (!defined $::proddesc{$name})))) + { + $user{'inallgroups'} &= $ingroup; + + push (@groups, { "bit" => $bit, + "ison" => $ison, + "ingroup" => $ingroup, + "description" => $description }); } - print "Accept bug (${extra}change status to <b>ASSIGNED</b>)<br>"; - $knum++; - } - if ($bug{'resolution'} ne "") { - print "<INPUT TYPE=radio NAME=knob VALUE=clearresolution>\n"; - print "Clear the resolution (remove the current resolution of\n"; - print "<b>$bug{'resolution'}</b>)<br>\n"; - $knum++; - } - my $resolution_popup = make_options(\@::settable_resolution, - $bug{'resolution'}); - print "<INPUT TYPE=radio NAME=knob VALUE=resolve> - Resolve bug, changing <A HREF=\"bug_status.html\">resolution</A> to - <SELECT NAME=resolution - ONCHANGE=\"document.changeform.knob\[$knum\].checked=true\"> - $resolution_popup</SELECT><br>\n"; - $knum++; - print "<INPUT TYPE=radio NAME=knob VALUE=duplicate> - Resolve bug, mark it as duplicate of bug # - <INPUT NAME=dup_id SIZE=6 ONCHANGE=\"if (this.value != '') {document.changeform.knob\[$knum\].checked=true}\"><br>\n"; - $knum++; - my $assign_element = "<INPUT NAME=\"assigned_to\" SIZE=32 ONCHANGE=\"if ((this.value != ".SqlQuote($bug{'assigned_to_email'}) .") && (this.value != '')) { document.changeform.knob\[$knum\].checked=true; }\" VALUE=\"$bug{'assigned_to_email'}\">"; - - print "<INPUT TYPE=radio NAME=knob VALUE=reassign> - <A HREF=\"bug_status.html#assigned_to\">Reassign</A> bug to - $assign_element - <br>\n"; - if ($status eq $::unconfirmedstate && ($canconfirm || $canedit)) { - print " <INPUT TYPE=checkbox NAME=andconfirm> and confirm bug (change status to <b>NEW</b>)<BR>"; - } - $knum++; - print "<INPUT TYPE=radio NAME=knob VALUE=reassignbycomponent> - Reassign bug to owner "; - if (Param("useqacontact")) { print "and QA contact "; } - print "of selected component<br>\n"; - if ($status eq $::unconfirmedstate && ($canconfirm || $canedit)) { - print " <INPUT TYPE=checkbox NAME=compconfirm> and confirm bug (change status to <b>NEW</b>)<BR>"; - } - $knum++; - } elsif ( Param("move-enabled") && ($bug{'resolution'} eq "MOVED") ) { - if ( (defined $::COOKIE{"Bugzilla_login"}) - && ($::COOKIE{"Bugzilla_login"} =~ /($movers)/) ){ - print "<INPUT TYPE=radio NAME=knob VALUE=reopen> Reopen bug<br>\n"; - $knum++; - if ($status eq "RESOLVED") { - print "<INPUT TYPE=radio NAME=knob VALUE=verify> - Mark bug as <b>VERIFIED</b><br>\n"; - $knum++; - } - if ($status ne "CLOSED") { - print "<INPUT TYPE=radio NAME=knob VALUE=close> - Mark bug as <b>CLOSED</b><br>\n"; - $knum++; - } } - } else { - print "<INPUT TYPE=radio NAME=knob VALUE=reopen> Reopen bug<br>\n"; - $knum++; - if ($status eq "RESOLVED") { - print "<INPUT TYPE=radio NAME=knob VALUE=verify> - Mark bug as <b>VERIFIED</b><br>\n"; - $knum++; - } - if ($status ne "CLOSED") { - print "<INPUT TYPE=radio NAME=knob VALUE=close> - Mark bug as <b>CLOSED</b><br>\n"; - $knum++; + + # If the bug is restricted to a group, display checkboxes that allow + # the user to set whether or not the reporter + # and cc list can see the bug even if they are not members of all + # groups to which the bug is restricted. + if ($bug{'groupset'} != 0) { + $bug{'inagroup'} = 1; + + # Determine whether or not the bug is always accessible by the + # reporter, QA contact, and/or users on the cc: list. + SendSQL("SELECT reporter_accessible, cclist_accessible + FROM bugs + WHERE bug_id = $id + "); + ($bug{'reporter_accessible'}, + $bug{'cclist_accessible'}) = FetchSQLData(); } + + $vars->{'groups'} = \@groups; } -} - -print " -<INPUT TYPE=\"submit\" VALUE=\"Commit\"> -<INPUT TYPE=\"reset\" VALUE=\"Reset\"> -<INPUT TYPE=\"hidden\" name=\"form_name\" VALUE=\"process_bug\"> -<P> -<FONT size=\"+1\"><B> - <A HREF=\"show_activity.cgi?id=$id\">View Bug Activity</A> - | - <A HREF=\"long_list.cgi?buglist=$id\">Format For Printing</A> -</B></FONT> -"; - -if ( Param("move-enabled") && (defined $::COOKIE{"Bugzilla_login"}) && ($::COOKIE{"Bugzilla_login"} =~ /($movers)/) ){ - print " <FONT size=\"+1\"><B> | </B></FONT> " - ."<INPUT TYPE=\"SUBMIT\" NAME=\"action\" VALUE=\"" - . Param("move-button-text") . "\">\n"; -} -print "<BR></FORM>"; - -print qq| -<table><tr><td align=left><B><a name="c0" href="#c0">Description:</a></B></td> -<td align=right width=100%>Opened: $bug{'creation_ts'}</td></tr></table> -<HR> -|; -print $bug{'long_desc'}; -print " -<HR>\n"; + my $movers = Param("movers"); + $user{'canmove'} = Param("move-enabled") + && (defined $::COOKIE{"Bugzilla_login"}) + && ($::COOKIE{"Bugzilla_login"} =~ /\Q$movers\E/); + + # User permissions + + # In the below, if the person hasn't logged in ($::userid == 0), then + # we treat them as if they can do anything. That's because we don't + # know why they haven't logged in; it may just be because they don't + # use cookies. Display everything as if they have all the permissions + # in the world; their permissions will get checked when they log in + # and actually try to make the change. + $user{'canedit'} = $::userid == 0 + || $::userid == $bug{'reporter'} + || $::userid == $bug{'qa_contact'} + || $::userid == $bug{'assigned_to'} + || UserInGroup("editbugs"); + $user{'canconfirm'} = ($::userid == 0) || UserInGroup("canconfirm"); + + # Bug states + $bug{'isunconfirmed'} = ($bug{'bug_status'} eq $::unconfirmedstate); + $bug{'isopened'} = IsOpenedState($bug{'bug_status'}); + + # People involved with the bug + $bug{'assigned_to_email'} = DBID_to_name($bug{'assigned_to'}); + $bug{'assigned_to'} = DBID_to_real_or_loginname($bug{'assigned_to'}); + $bug{'reporter'} = DBID_to_real_or_loginname($bug{'reporter'}); + $bug{'qa_contact'} = $bug{'qa_contact'} > 0 ? + DBID_to_name($bug{'qa_contact'}) : ""; + + my $ccset = new RelationSet; + $ccset->mergeFromDB("SELECT who FROM cc WHERE bug_id=$id"); + + my @cc = $ccset->toArrayOfStrings(); + $bug{'cc'} = \@cc if $cc[0]; + + # Next bug in list (if there is one) + if ($::COOKIE{"BUGLIST"} && $id) + { + my @bug_list = split(/:/, $::COOKIE{"BUGLIST"}); + $vars->{'bug_list'} = \@bug_list; + } -# To add back option of editing the long description, insert after the above -# long_list.cgi line: -# <A HREF=\"edit_desc.cgi?id=$id\">Edit Long Description</A> + $bug{'comments'} = GetComments($bug{'bug_id'}); -navigation_header(); + # This is length in number of comments + $bug{'longdesclength'} = scalar(@{$bug{'comments'}}); -PutFooter(); + # Add the bug and user hashes to the variables + $vars->{'bug'} = \%bug; + $vars->{'user'} = \%user; + # Generate and return the UI (HTML page) from the appropriate template. + $template->process("show/show_bug.html.tmpl", $vars) + || DisplayError("Template process failed: " . $template->error()) + && exit; +} + 1; diff --git a/process_bug.cgi b/process_bug.cgi index fb3c0e482..6af364666 100755 --- a/process_bug.cgi +++ b/process_bug.cgi @@ -32,22 +32,25 @@ my $UserInCanConfirmGroupSet = -1; use lib qw(.); require "CGI.pl"; +require "bug_form.pl"; + use RelationSet; # Shut up misguided -w warnings about "used only once": -use vars %::versions, - %::components, - %::COOKIE, - %::MFORM, - %::legal_keywords, - %::legal_opsys, - %::legal_platform, - %::legal_priority, - %::settable_resolution, - %::target_milestone, - %::legal_severity, - %::superusergroupset; +use vars qw(%versions + %components + %COOKIE + %MFORM + %legal_keywords + %legal_opsys + %legal_platform + %legal_priority + %settable_resolution + %target_milestone + %legal_severity + %superusergroupset + $next_bug); my $whoid = confirm_login(); @@ -466,22 +469,8 @@ if ($action eq Param("move-button-text")) { # the common updates to all bugs in @idlist start here # print "<TITLE>Update Bug " . join(" ", @idlist) . "</TITLE>\n"; -if (defined $::FORM{'id'}) { - navigation_header(); - if (defined $::next_bug) { - # If there is another bug, then we're going to display it, - # so check that its a legal bug - # We need to check that its a number first - if (!(detaint_natural($::next_bug) && CanSeeBug($::next_bug))) { - # This isn't OK - # Rather than error out (which could validly happen if there - # was a bug in the list whose group was changed in the meantime) - # just remove references to it - undef $::next_bug; - } - } -} print "<HR>\n"; + $::query = "update bugs\nset"; $::comma = ""; umask(0); @@ -973,13 +962,20 @@ The changes made were: <p> "; DumpBugActivity($id, $::FORM{'delta_ts'}); - my $longdesc = GetLongDescriptionAsHTML($id); + my $comments = GetComments($id); my $longchanged = 0; - if (length($longdesc) > $::FORM{'longdesclength'}) { + if (scalar(@$comments) > $::FORM{'longdesclength'}) { $longchanged = 1; print "<P>Added text to the long description:<blockquote>"; - print substr($longdesc, $::FORM{'longdesclength'}); + use vars qw($template $vars); + $vars->{'start_at'} = $::FORM{'longdesclength'}; + $vars->{'comments'} = $comments; + $vars->{'quoteUrls'} = \"eUrls; + $template->process("show/comments.tmpl", $vars) + || DisplayError("Template process failed: " . $template->error()) + && exit; + print "</blockquote>\n"; } SendSQL("unlock tables"); @@ -1394,14 +1390,29 @@ The changes made were: } -if (defined $::next_bug) { - print("<P>The next bug in your list is:\n"); - $::FORM{'id'} = $::next_bug; - print "<HR>\n"; +# Show next bug, if it exists. +if ($::COOKIE{"BUGLIST"} && $::FORM{'id'}) { + my @bugs = split(/:/, $::COOKIE{"BUGLIST"}); + my $cur = lsearch(\@bugs, $::FORM{"id"}); + if ($cur >= 0 && $cur < $#bugs) { + my $next_bug = $bugs[$cur + 1]; + if (detaint_natural($next_bug) && CanSeeBug($next_bug)) { - navigation_header(); - do "bug_form.pl"; -} else { - navigation_header(); - PutFooter(); + print "<hr>\n"; + print("<p>The next bug in your list is bug "); + print("<a href='show_bug.cgi?id=$next_bug'>$next_bug</a>:</p>\n"); + $::FORM{'id'} = $next_bug; + + show_bug("header is already done"); + + exit; + } + else { + # Need this until the navigation_header() fn. goes away totally. + undef $::next_bug; + } + } } + +navigation_header(); +PutFooter(); diff --git a/show_bug.cgi b/show_bug.cgi index 28eb66763..f832a2930 100755 --- a/show_bug.cgi +++ b/show_bug.cgi @@ -26,6 +26,7 @@ use strict; use lib qw(.); require "CGI.pl"; +require "bug_form.pl"; ConnectToDatabase(); @@ -49,32 +50,8 @@ if (defined ($::FORM{'id'})) { # End Data/Security Validation ###################################################################### -print "Content-type: text/html\n"; -print "\n"; - -if (!defined $::FORM{'id'}) { - PutHeader("Search by bug number"); - print "<FORM METHOD=GET ACTION=\"show_bug.cgi\">\n"; - print "You may find a single bug by entering its bug id here: \n"; - print "<INPUT NAME=id>\n"; - print "<INPUT TYPE=\"submit\" VALUE=\"Show Me This Bug\">\n"; - print "</FORM>\n"; - PutFooter(); - exit; -} - GetVersionTable(); -# Get the bug's summary (short description) and display it as -# the page title. -SendSQL("SELECT short_desc FROM bugs WHERE bug_id = $::FORM{'id'}"); -my ($summary) = FetchSQLData(); -$summary = html_quote($summary); -PutHeader("Bug $::FORM{'id'} - $summary", "Bugzilla Bug $::FORM{'id'}", $summary, "", navigation_links() ); - -navigation_header(); - -print "<HR>\n"; +print "Content-type: text/html\n\n"; -$! = 0; -do "bug_form.pl" || die "Error doing bug_form.pl: $!"; +show_bug(); diff --git a/template/default/show/choose_bug.html.tmpl b/template/default/show/choose_bug.html.tmpl new file mode 100644 index 000000000..1df89ce8f --- /dev/null +++ b/template/default/show/choose_bug.html.tmpl @@ -0,0 +1,35 @@ +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # The Initial Developer of the Original Code is Netscape Communications + # Corporation. Portions created by Netscape are + # Copyright (C) 1998 Netscape Communications Corporation. All + # Rights Reserved. + # + # Contributor(s): Gervase Markham <gerv@gerv.net> + #%] + +[% UNLESS header_done %] + [% INCLUDE global/header + title = "Search by bug number" + %] +[% END %] + +<form method="get" action="show_bug.cgi"> + <p> + You may find a single bug by entering its bug id here: + <input name="id" size="6"> + <input type="submit" value="Show Me This Bug"> + </p> +</form> + +[% INCLUDE global/footer %] diff --git a/template/default/show/navigate.html.tmpl b/template/default/show/navigate.html.tmpl new file mode 100644 index 000000000..685539e01 --- /dev/null +++ b/template/default/show/navigate.html.tmpl @@ -0,0 +1,53 @@ +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # The Initial Developer of the Original Code is Netscape Communications + # Corporation. Portions created by Netscape are + # Copyright (C) 1998 Netscape Communications Corporation. All + # Rights Reserved. + # + # Contributor(s): Gervase Markham <gerv@gerv.net> + #%] + +[% IF bug_list.size > 0 %] + [% this_bug_idx = lsearch(bug_list, bug.bug_id) %] + <b>Bug List:</b> + [% IF this_bug_idx != -1 %] + ([% this_bug_idx + 1 %] of [% bug_list.size %]) + [% END %] + + <a href="show_bug.cgi?id=[% bug_list.first %]">First</a> + <a href="show_bug.cgi?id=[% bug_list.last %]">Last</a> + + [% IF this_bug_idx != -1 %] + [% IF this_bug_idx > 0 %] + [% prev_bug = this_bug_idx - 1 %] + <a href="show_bug.cgi?id=[% bug_list.$prev_bug %]">Prev</a> + [% ELSE %] + <i><font color="#777777">Prev</font></i> + [% END %] + + [% IF this_bug_idx + 1 < bug_list.size %] + [% next_bug = this_bug_idx + 1 %] + <a href="show_bug.cgi?id=[% bug_list.$next_bug %]">Next</a> + [% ELSE %] + <i><font color="#777777">Next</font></i> + [% END %] + [% ELSE %] + (This bug is not in your list) + [% END %] + + <a href="buglist.cgi?regetlastlist=1">Show list</a> +[% END %] + + <a href="query.cgi">Query page</a> + <a href="enter_bug.cgi">Enter new bug</a> diff --git a/template/default/show/show_bug.html.tmpl b/template/default/show/show_bug.html.tmpl new file mode 100644 index 000000000..13eb80034 --- /dev/null +++ b/template/default/show/show_bug.html.tmpl @@ -0,0 +1,527 @@ +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # The Initial Developer of the Original Code is Netscape Communications + # Corporation. Portions created by Netscape are + # Copyright (C) 1998 Netscape Communications Corporation. All + # Rights Reserved. + # + # Contributor(s): Gervase Markham <gerv@gerv.net> + #%] + +[% UNLESS header_done %] + [% INCLUDE global/header + title = "Bug $bug.bug_id - $bug.short_desc" + h1 = "Bugzilla Bug $bug.bug_id" + h2 = bug.short_desc + extra = navigation_links() + %] +[% END %] + +[% PROCESS show/navigate.html.tmpl %] + +<hr> + +<form name="changeform" method="post" action="process_bug.cgi"> + + <input type="hidden" name="delta_ts" value="[% bug.delta_ts %]"> + <input type="hidden" name="longdesclength" value="[% bug.longdesclength %]"> + <input type="hidden" name="id" value="[% bug.bug_id %]"> + +[%# *** Platform Reporter Product OS AddCC *** %] + + <table cellspacing="1" cellpadding="1" border="0"> + <tr> + <td align="right"> + <b>Bug#:</b> + </td> + <td> + <a href="[% urlbase %]show_bug.cgi?id=[% bug.bug_id %]"> + [% bug.bug_id %]</a> + </td> + + <td> </td> + + <td align="right"> + <b>Platform:</b> + </td> + [% PROCESS select selname = "rep_platform" %] + + <td align="right"> + <b>Reporter:</b> + </td> + <td> + [% bug.reporter %] + </td> + </tr> + + <tr> + <td align="right"> + <b>Product:</b> + </td> + [% PROCESS select selname => "product" %] + + <td align="right"> + <b>OS:</b> + </td> + [% PROCESS select selname => "op_sys" %] + + <td align="right"> + <b>Add CC:</b> + </td> + <td> + <input name="newcc" size="30" value=""> + </td> + </tr> + +[%# *** Component Version CC Priority Severity AssignedTo Milestone *** %] + + <tr> + <td align="right"> + <b> + <a href="describecomponents.cgi?product=[% bug.product %]"> + Component</a>: + </b> + </td> + <td> + <select name="component"> + [% FOREACH x = component_ %] + <option value="[% x %]" + [% " selected" IF x == bug.component_ %]>[% x %]</option> + [% END %] + </select> + </td> + + <td> </td> + + <td align="right"> + <b>Version:</b> + </td> + [% PROCESS select selname => "version" %] + + <td rowspan="4" align="right" valign="top"> + <b>CC:</b> + </td> + <td rowspan="4" valign="top"> + [% IF bug.cc %] + <select name="cc" multiple size="5"> + [% FOREACH c = bug.cc %] + <option value="[% c %]">[% c %]</option> + [% END %] + </select> + <br> + <input type="checkbox" name="removecc">Remove selected CCs + <br> + [% ELSE %] + <input type="hidden" name="cc" value=""> + [% END %] + </td> + </tr> + + <tr> + <td align="right"> + <b> + <a href="bug_status.html">Status</a>: + </b> + </td> + <td>[% bug.bug_status %]</td> + <td> </td> + + <td align="right"> + <b><a href="bug_status.html#priority">Priority</a>:</b> + </td> + [% PROCESS select selname => "priority" %] + </tr> + + <tr> + <td align="right"> + <b> + <a href="bug_status.html">Resolution</a>: + </b> + </td> + <td>[% bug.resolution %]</td> + <td> </td> + + <td align="right"> + <b><a href="bug_status.html#severity">Severity</a>:</b> + </td> + [% PROCESS select selname = "bug_severity" %] + + </tr> + + <tr> + <td align="right"> + <b> + <a href="bug_status.html#assigned_to">Assigned To</a>: + </b> + </td> + <td>[% bug.assigned_to %]</td> + <td> </td> + + [% IF Param("usetargetmilestone") && bug.target_milestone %] + <td align="right"> + <b> + <a href="[% bug.milestoneurl %]">Target Milestone</a>: + </b> + </td> + [% PROCESS select selname = "target_milestone" %] + [% ELSE %] + <td colspan="3"> </td> + [% END %] + </tr> + +[%# *** QAContact URL Summary Whiteboard Keywords *** %] + + [% IF Param('useqacontact') %] + <tr> + <td align="right"> + <b>QA Contact:</b> + </td> + <td colspan="7"> + <input name="qa_contact" value="[% bug.qa_contact %]" size="60"> + </td> + </tr> + [% END %] + + <tr> + <td align="right"> + <b> + [% IF bug.url %] + <a href="[% bug.url FILTER url %]">URL:</a> + [% ELSE %] + URL: + [% END %] + </td> + <td colspan="7"> + <input name="bug_file_loc" value="[% bug.bug_file_loc %]" size="60"> + </td> + </tr> + + <tr> + <td align="right"> + <b>Summary:</b> + </td> + <td colspan="7"> + <input name="short_desc" value="[% bug.short_desc %]" size="60"> + </td> + </tr> + + [% IF Param('usestatuswhiteboard') %] + <tr> + <td align="right"> + <b>Status Whiteboard:</b> + </td> + <td colspan="7"> + <input name="status_whiteboard" value="[% bug.status_whiteboard %]" + size="60"> + </td> + </tr> + [% END %] + + [% IF use_keywords %] + <tr> + <td ALIGN="right"> + <b> + <A HREF="describekeywords.cgi">Keywords:</A> + </b> + <td colspan="7"> + <input name="keywords" value="[% bug.keywords.join(', ') %]" + size="60"> + </td> + </tr> + [% END %] + </table> + +[%# *** Attachments *** %] + + [% INCLUDE attachment/list.atml + attachments = bug.attachments %] + +[%# *** Dependencies Votes *** %] + + [% IF Param('usedependencies') %] + <table> + <tr> + [% PROCESS dependencies + dep = { title => "depends on", fieldname => "dependson" } %] + <td rowspan="2"> + <a href="showdependencytree.cgi?id=[% bug.bug_id %]">Show + dependency tree</a> + + [% IF Param('webdotbase') %] + <br> + <a href="showdependencygraph.cgi?id=[% bug.bug_id %]">Show + dependency graph</a> + [% END %] + </td> + </tr> + + <tr> + [% PROCESS dependencies + dep = { title => "blocks", fieldname => "blocked" } %] + </tr> + </table> + [% END %] + + [% IF use_votes %] + <table> + <tr> + <th> + <a href="votehelp.html">Votes:</a> + </th> + <td> + [% bug.votes %] + <a href="showvotes.cgi?bug_id=[% bug.bug_id %]">Show votes for this + bug</a> + <a href="showvotes.cgi?voteon=[% bug.bug_id %]">Vote for this bug</a> + </td> + </tr> + </table> + [% END %] + +[%# *** Comments Groups *** %] + + <br> + <b>Additional Comments:</b> + <br> + <textarea wrap="hard" name="comment" rows="10" cols="80" + accesskey="c"></textarea> + <br> + + [% IF groups %] + <br> + <b>Only users in the selected groups can view this bug:</b> + <br> + <font size="-1">(Unchecking all boxes makes this a public bug.)</font> + <br> + <br> + + [% FOREACH group = groups %] + + <input type="checkbox" name="bit-[% group.bit %]" value="1" + [% " checked='checked'" IF group.ison %] + [% " disabled='disabled'" IF NOT group.ingroup %]> + [% group.description %] + <br> + [% END %] + + [% IF NOT user.inallgroups %] + <b> + Only members of a group can change the visibility of a bug for + that group + </b> + <br> + [% END %] + + [% IF bug.inagroup %] + <p> + <b>But users in the roles selected below can always view this bug:</b> + <br> + <small> + (The assignee + [% IF (Param('useqacontact')) %] + and qa contact + [% END %] + can always see a bug, and this section does not take effect unless + the bug is restricted to at least one group.) + </small> + </p> + + <p> + <input type="checkbox" name="reporter_accessible" value="1" + [% " checked" IF bug.reporter_accessible %]>Reporter + <input type="checkbox" name="cclist_accessible" value="1" + [% " checked" IF bug.cclist_accessible %]>CC List + </p> + [% END %] + [% END %] + +[%# *** Knob *** %] + + <br> + <input type="radio" name="knob" value="none" checked> + Leave as <b>[% bug.bug_status %] [% bug.resolution %]</b> + <br> + + [% knum = 1 %] + + [% IF bug.bug_status == "UNCONFIRMED" && + (user.canedit || user.canconfirm) %] + <input type="radio" name="knob" value="confirm"> + Confirm bug (change status to <b>NEW</b>) + <br> + [% knum = knum + 1 %] + [% END %] + + [% IF user.canedit %] + [% IF bug.isopened %] + [% IF bug.bug_status != "ASSIGNED" %] + <input type="radio" name="knob" value="accept"> + Accept bug ( + [% "confirm bug, " IF bug.isunconfirmed %]change + status to <b>ASSIGNED</b>) + <br> + [% knum = knum + 1 %] + [% END %] + + [% IF bug.resolution %] + <input type="radio" name="knob" value="clearresolution"> + Clear the resolution (remove the current resolution of + <b>[% bug.resolution %]</b>)<br> + [% knum = knum + 1 %] + [% END %] + + <input type="radio" name="knob" value="resolve"> + Resolve bug, changing <A HREF="bug_status.html">resolution</A> to + <select name="resolution" + onchange="document.changeform.knob[[% knum %]].checked=true"> + [% FOREACH r = resolution %] + <option value="[% r %]">[% r %]</option> + [% END %] + </select> + <br> + [% knum = knum + 1 %] + + <input type="radio" name="knob" value="duplicate"> + Resolve bug, mark it as duplicate of bug # + <input name="dup_id" size="6" + onchange="if (this.value != '') + {document.changeform.knob[[% knum %]].checked=true}"> + <br> + [% knum = knum + 1 %] + + <input type="radio" name="knob" value="reassign"> + <a href="bug_status.html#assigned_to">Reassign</A> bug to + <input name="assigned_to" size="32" + onchange="if ((this.value != "[% bug.assigned_to_email %]") && + (this.value != '')) { + document.changeform.knob[[% knum %]].checked=true; + }" + value="[% bug.assigned_to_email %]"> + <br> + [% IF bug.isunconfirmed %] + <input type="checkbox" name="andconfirm"> + and confirm bug (change status to <b>NEW</b>) + <br> + [% END %] + [% knum = knum + 1 %] + + <input type="radio" name="knob" value="reassignbycomponent"> + Reassign bug to owner + [% "and QA contact" IF useqacontact %] + of selected component + <br> + [% IF bug.isunconfirmed %] + <input type="checkbox" name="andconfirm"> + and confirm bug (change status to <b>NEW</b>) + <br> + [% END %] + [% knum = knum + 1 %] + [% ELSE %] + [% IF bug.resolution != "MOVED" || + (bug.resolution == "MOVED" && user.canmove) %] + <input type="radio" name="knob" value="reopen"> Reopen bug + <br> + [% knum = knum + 1 %] + [% END %] + [% IF bug.bug_status == "RESOLVED" %] + <input type="radio" name="knob" value="verify"> + Mark bug as <b>VERIFIED</b><br> + [% knum = knum + 1 %] + [% END %] + [% IF bug.bug_status != "CLOSED" %] + <input type="radio" name="knob" value="close"> + Mark bug as <b>CLOSED</b><br> + [% knum = knum + 1 %] + [% END %] + [% END %] + [% END %] + + <input type="submit" value="Commit"> + <input type="hidden" name="form_name" value="process_bug"> + <p> + <font size="+1"> + <b> + <A HREF="show_activity.cgi?id=[% bug.bug_id %]">View Bug Activity</A> + | + <A HREF="long_list.cgi?buglist=[% bug.bug_id %]">Format For Printing</A> + </b> + </font> + + [% IF user.canmove %] + <font size="+1"><b> | </b></font> + <input type="submit" name="action" + value="[% Param("move-button-text") %]"> + [% END %] + </p> +</form> + +[%# *** Additional Comments *** %] + +<table> + <tr> + <td align="left"> + <b> + <a name="c0" href="#c0">Description</a>: + </b> + </td> + <td align="right" width="100%"> + Opened: [% bug.creation_ts %] + </td> + </tr> +</table> +<hr> + +[% PROCESS show/comments.tmpl %] + +<hr> + +[% PROCESS show/navigate.html.tmpl %] + +<br> + +[% INCLUDE global/footer %] + + +[%############################################################################%] +[%# Block for dependencies #%] +[%############################################################################%] + +[% BLOCK dependencies %] + <th align="right">Bug [% bug.bug_id %] [%+ dep.title %]:</th> + <td> + [% FOREACH depbug = bug.${dep.fieldname} %] + [% GetBugLink(depbug, depbug) %][% " " %] + [% END %] + </td> + <td> + <input name="[% dep.fieldname %]" + value="[% bug.${dep.fieldname}.join(', ') %]"> + </td> +[% END %] + + +[%############################################################################%] +[%# Block for SELECT fields #%] +[%############################################################################%] + +[% BLOCK select %] + <td> + <select name="[% selname %]"> + [% FOREACH x = ${selname} %] + <option value="[% x %]" + [% " selected" IF x == bug.${selname} %]>[% x %]</option> + [% END %] + </select> + </td> + <td> </td> +[% END %] |