bug_form.pl 17.5 KB
Newer Older
1 2
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
3 4 5 6 7 8 9 10 11 12
# 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.
#
13
# The Original Code is the Bugzilla Bug Tracking System.
14
#
15
# The Initial Developer of the Original Code is Netscape Communications
16 17 18 19
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
20
# Contributor(s): Terry Weissman <terry@mozilla.org>
21
#                 Dave Miller <dave@intrec.com>
22 23 24 25

use diagnostics;
use strict;

26 27
use RelationSet;

28 29 30 31 32 33 34 35 36
# 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 = %::prodmaxvotes;
    $zz = %::versions;
37
    $zz = @::legal_keywords;
38 39 40 41
    $zz = @::legal_opsys;
    $zz = @::legal_platform;
    $zz = @::legal_product;
    $zz = @::legal_priority;
42
    $zz = @::settable_resolution;
43
    $zz = @::legal_severity;
44
    $zz = %::target_milestone;
45
}
46

47
my $loginok = quietly_check_login();
48

49 50
my $id = $::FORM{'id'};

51 52
my $query = "
select
53
        bugs.bug_id,
54 55 56 57 58 59 60 61 62 63 64 65 66
        product,
        version,
        rep_platform,
        op_sys,
        bug_status,
        resolution,
        priority,
        bug_severity,
        component,
        assigned_to,
        reporter,
        bug_file_loc,
        short_desc,
67 68 69
	target_milestone,
	qa_contact,
	status_whiteboard,
70
        date_format(creation_ts,'%Y-%m-%d %H:%i'),
71
        groupset,
72 73 74 75 76 77
	delta_ts,
	sum(votes.count)
from bugs left join votes using(bug_id)
where bugs.bug_id = $id
and bugs.groupset & $::usergroupset = bugs.groupset
group by bugs.bug_id";
78 79 80 81 82 83 84 85 86

SendSQL($query);
my %bug;
my @row;
if (@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",
87
		       "bug_file_loc", "short_desc", "target_milestone",
88
                       "qa_contact", "status_whiteboard", "creation_ts",
89
                       "groupset", "delta_ts", "votes") {
90 91 92 93 94 95 96
	$bug{$field} = shift @row;
	if (!defined $bug{$field}) {
	    $bug{$field} = "";
	}
	$count++;
    }
} else {
97
    SendSQL("select groupset from bugs where bug_id = $id");
98 99 100 101
    if (@row = FetchSQLData()) {
        print "<H1>Permission denied.</H1>\n";
        if ($loginok) {
            print "Sorry; you do not have the permissions necessary to see\n";
102
            print "bug $id.\n";
103
        } else {
104
            print "Sorry; bug $id can only be viewed when logged\n";
105 106
            print "into an account with the appropriate permissions.  To\n";
            print "see this bug, you must first\n";
107
            print "<a href=\"show_bug.cgi?id=$id&GoAheadAndLogIn=1\">";
108 109 110 111
            print "log in</a>.";
        }
    } else {
        print "<H1>Bug not found</H1>\n";
112
        print "There does not seem to be a bug numbered $id.\n";
113
    }
114
    PutFooter();
115
    exit;
116 117
}

118 119 120 121
my $assignedtoid = $bug{'assigned_to'};
my $reporterid = $bug{'reporter'};
my $qacontactid =  $bug{'qa_contact'};

122
$bug{'assigned_to_email'} = DBID_to_name($assignedtoid);
123 124
$bug{'assigned_to'} = DBID_to_real_or_loginname($bug{'assigned_to'});
$bug{'reporter'} = DBID_to_real_or_loginname($bug{'reporter'});
125 126 127 128 129 130 131 132

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};
#  }

133
$bug{'long_desc'} = GetLongDescriptionAsHTML($id);
134
my $longdesclength = length($bug{'long_desc'});
135 136 137

GetVersionTable();

138 139


140 141 142 143 144 145 146 147 148 149 150 151
#
# 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'});

152 153
my $ccSet = new RelationSet;
$ccSet->mergeFromDB("select who from cc where bug_id=$id");
154 155 156 157 158 159 160 161 162 163
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";
}
164

165
my $URL = value_quote($bug{'bug_file_loc'});
166 167 168 169 170 171 172 173

if (defined $URL && $URL ne "none" && $URL ne "NULL" && $URL ne "") {
    $URL = "<B><A HREF=\"$URL\">URL:</A></B>";
} else {
    $URL = "<B>URL:</B>";
}

print "
174 175
<INPUT TYPE=HIDDEN NAME=\"delta_ts\" VALUE=\"$bug{'delta_ts'}\">
<INPUT TYPE=HIDDEN NAME=\"longdesclength\" VALUE=\"$longdesclength\">
176
<INPUT TYPE=HIDDEN NAME=\"id\" VALUE=$id>
177
  <TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0><TR>
178
    <TD ALIGN=RIGHT><B>Bug#:</B></TD><TD><A HREF=\"" . Param('urlbase') . "show_bug.cgi?id=$bug{'bug_id'}\">$bug{'bug_id'}</A></TD>
179
  <TD>&nbsp;</TD>
180 181
    <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html#rep_platform\">Platform:</A></B></TD>
    <TD><SELECT NAME=rep_platform>$platform_popup</SELECT></TD>
182 183 184
  <TD>&nbsp;</TD>
    <TD ALIGN=RIGHT><B>Reporter:</B></TD><TD>$bug{'reporter'}</TD>
</TR><TR>
185 186 187 188
    <TD ALIGN=RIGHT><B>Product:</B></TD>
    <TD><SELECT NAME=product>" .
    make_options(\@::legal_product, $bug{'product'}) .
    "</SELECT></TD>
189
  <TD>&nbsp;</TD>
190 191 192
    <TD ALIGN=RIGHT><B>OS:</B></TD>
    <TD><SELECT NAME=op_sys>" .
    make_options(\@::legal_opsys, $bug{'op_sys'}) .
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
    "</SELECT></TD>
  <TD>&nbsp;</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>&nbsp;</TD>
    <TD ALIGN=RIGHT><B>Version:</B></TD>
    <TD><SELECT NAME=version>" .
    make_options($::versions{$bug{'product'}}, $bug{'version'}) .
    "</SELECT></TD>
  <TD>&nbsp;</TD>
    <TD ROWSPAN=4 ALIGN=RIGHT VALIGN=TOP><B>Cc:</B></TD>
    <TD ROWSPAN=4 VALIGN=TOP> $cc_element </TD>
</TR><TR>
210 211
    <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html\">Status:</A></B></TD>
      <TD>$bug{'bug_status'}</TD>
212
  <TD>&nbsp;</TD>
213 214
    <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html#priority\">Priority:</A></B></TD>
      <TD><SELECT NAME=priority>$priority_popup</SELECT></TD>
215 216
  <TD>&nbsp;</TD>
</TR><TR>
217 218
    <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html\">Resolution:</A></B></TD>
      <TD>$bug{'resolution'}</TD>
219
  <TD>&nbsp;</TD>
220 221
    <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html#severity\">Severity:</A></B></TD>
      <TD><SELECT NAME=bug_severity>$sev_popup</SELECT></TD>
222 223
  <TD>&nbsp;</TD>
</TR><TR>
224 225
    <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html#assigned_to\">Assigned&nbsp;To:
        </A></B></TD>
226 227
      <TD>$bug{'assigned_to'}</TD>
  <TD>&nbsp;</TD>";
228 229

if (Param("usetargetmilestone")) {
230 231 232 233 234 235 236
    my $url = "";
    if (defined $::milestoneurl{$bug{'product'}}) {
        $url = $::milestoneurl{$bug{'product'}};
    }
    if ($url eq "") {
        $url = "notargetmilestone.html";
    }
237 238 239
    if ($bug{'target_milestone'} eq "") {
        $bug{'target_milestone'} = " ";
    }
240
    print "
241
<TD ALIGN=RIGHT><A href=\"$url\"><B>Target Milestone:</B></A></TD>
242
<TD><SELECT NAME=target_milestone>" .
243
    make_options($::target_milestone{$bug{'product'}},
244
                 $bug{'target_milestone'}) .
245 246 247
                     "</SELECT></TD>
  <TD>&nbsp;</TD>";
} else { print "<TD></TD><TD></TD><TD>&nbsp;</TD>"; }
248 249 250 251 252 253 254 255 256

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>
257
    <TD COLSPAN=7>
258 259
      <INPUT NAME=qa_contact VALUE=\"" .
    value_quote($name) .
260
    "\" SIZE=60></TD>
261 262 263 264 265 266
  </TR>";
}


print "
  <TR>
267
    <TD ALIGN=\"RIGHT\">$URL
268
    <TD COLSPAN=7>
269
      <INPUT NAME=bug_file_loc VALUE=\"" . value_quote($bug{'bug_file_loc'}) . "\" SIZE=60></TD>
270 271
  </TR><TR>
    <TD ALIGN=\"RIGHT\"><B>Summary:</B>
272
    <TD COLSPAN=7>
273 274 275
      <INPUT NAME=short_desc VALUE=\"" .
    value_quote($bug{'short_desc'}) .
    "\" SIZE=60></TD>
276 277 278 279 280 281
  </TR>";

if (Param("usestatuswhiteboard")) {
    print "
  <TR>
    <TD ALIGN=\"RIGHT\"><B>Status Whiteboard:</B>
282
    <TD COLSPAN=7>
283 284
      <INPUT NAME=status_whiteboard VALUE=\"" .
    value_quote($bug{'status_whiteboard'}) .
285
    "\" SIZE=60></TD>
286 287 288
  </TR>";
}

289 290 291 292 293 294 295 296 297
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());
    }
298
    my $value = value_quote(join(', ', @list));
299 300
    print qq{
<TR>
301
<TD ALIGN=right><B><A HREF="describekeywords.cgi">Keywords:</A></B>
302
<TD COLSPAN=7><INPUT NAME="keywords" VALUE="$value" SIZE=60></TD>
303 304 305 306
</TR>
};
}

307
print "<tr><td align=right><B>Attachments:</b></td>\n";
308
SendSQL("select attach_id, creation_ts, mimetype, description from attachments where bug_id = $id");
309
while (MoreSQLData()) {
310
    my ($attachid, $date, $mimetype, $desc) = (FetchSQLData());
311 312 313
    if ($date =~ /^(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/) {
        $date = "$3/$4/$2 $5:$6";
    }
314
    my $link = "showattachment.cgi?attach_id=$attachid";
315
    $desc = value_quote($desc);
316
    print qq{<td><a href="$link">$date</a></td><td colspan=6>$desc&nbsp;&nbsp;&nbsp;($mimetype)</td></tr><tr><td></td>};
317
}
318
print "<td colspan=7><a href=\"createattachment.cgi?id=$id\">Create a new attachment</a> (proposed patch, testcase, etc.)</td></tr></table>\n";
319 320 321 322 323 324


sub EmitDependList {
    my ($desc, $myfield, $targetfield) = (@_);
    print "<th align=right>$desc:</th><td>";
    my @list;
325 326
    SendSQL("select $targetfield from dependencies where  
             $myfield = $id order by $targetfield");
327
    while (MoreSQLData()) {
328
        my ($i) = (FetchSQLData());
329
        push(@list, $i);
330
        print GetBugLink($i, $i);
331 332 333 334
        print " ";
    }
    print "</td><td><input name=$targetfield value=\"" .
        join(',', @list) . "\"></td>\n";
335 336
}

337 338
if (Param("usedependencies")) {
    print "<table><tr>\n";
339
    EmitDependList("Bug $id depends on", "blocked", "dependson");
340 341 342 343 344 345 346 347 348
    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>";
349
    EmitDependList("Bug $id blocks", "dependson", "blocked");
350 351
    print "</tr></table>\n";
}
352

353 354 355 356 357 358 359 360 361 362
if ($::prodmaxvotes{$bug{'product'}}) {
    print qq{
<table><tr>
<th><a href="votehelp.html">Votes</a> for bug $id:</th><td>
<a href="showvotes.cgi?bug_id=$id">$bug{'votes'}</a>
&nbsp;&nbsp;&nbsp;<a href="showvotes.cgi?voteon=$id">Vote for this bug</a>
</td></tr></table>
};
}

363
print "
364 365 366
<br>
<B>Additional Comments:</B>
<BR>
367
<TEXTAREA WRAP=HARD NAME=comment ROWS=10 COLS=80></TEXTAREA><BR>";
368 369


370
if ($::usergroupset ne '0') {
371 372 373 374 375 376 377 378 379 380 381 382 383 384
    SendSQL("select bit, description, (bit & $bug{'groupset'} != 0) from groups where bit & $::usergroupset != 0 and isbuggroup != 0 order by bit");
    while (MoreSQLData()) {
        my ($bit, $description, $ison) = (FetchSQLData());
        my $check0 = !$ison ? " SELECTED" : "";
        my $check1 = $ison ? " SELECTED" : "";
        print "<select name=bit-$bit><option value=0$check0>\n";
        print "People not in the \"$description\" group can see this bug\n";
        print "<option value=1$check1>\n";
        print "Only people in the \"$description\" group can see this bug\n";
        print "</select><br>\n";
    }
}

print "<br>
385 386 387
<INPUT TYPE=radio NAME=knob VALUE=none CHECKED>
        Leave as <b>$bug{'bug_status'} $bug{'resolution'}</b><br>";

388

389 390 391 392 393 394
# knum is which knob number we're generating, in javascript terms.

my $knum = 1;

my $status = $bug{'bug_status'};

395 396 397 398 399 400 401 402
# 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);
403 404 405
my $canconfirm;

if ($status eq $::unconfirmedstate) {
406
    $canconfirm = UserInGroup("canconfirm") || ($::userid == 0);
407 408 409
    if ($canedit || $canconfirm) {
        print "<INPUT TYPE=radio NAME=knob VALUE=confirm>";
	print "Confirm bug (change status to <b>NEW</b>)<br>";
410 411
        $knum++;
    }
412 413
}

414 415 416
my $movers = Param("movers");
$movers =~ s/\s?,\s?/|/g;
$movers =~ s/@/\@/g;
417

418 419
if ($canedit || $::userid == $assignedtoid ||
      $::userid == $reporterid || $::userid == $qacontactid) {
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435
    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, ";
            }
            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++;
        }
436 437
        my $resolution_popup = make_options(\@::settable_resolution,
                                            $bug{'resolution'});
438
        print "<INPUT TYPE=radio NAME=knob VALUE=resolve>
439 440 441 442
        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";
443 444
        $knum++;
        print "<INPUT TYPE=radio NAME=knob VALUE=duplicate>
445 446
        Resolve bug, mark it as duplicate of bug # 
        <INPUT NAME=dup_id SIZE=6 ONCHANGE=\"document.changeform.knob\[$knum\].checked=true\"><br>\n";
447
        $knum++;
448
        my $assign_element = "<INPUT NAME=\"assigned_to\" SIZE=32 ONCHANGE=\"document.changeform.knob\[$knum\].checked=true\" VALUE=\"$bug{'assigned_to_email'}\">";
449

450
        print "<INPUT TYPE=radio NAME=knob VALUE=reassign> 
451 452 453
          <A HREF=\"bug_status.html#assigned_to\">Reassign</A> bug to
          $assign_element
        <br>\n";
454 455 456 457 458
        if ($status eq $::unconfirmedstate && ($canconfirm || $canedit)) {
            print "&nbsp;&nbsp;&nbsp;&nbsp;<INPUT TYPE=checkbox NAME=andconfirm> and confirm bug (change status to <b>NEW</b>)<BR>";
        }
        $knum++;
        print "<INPUT TYPE=radio NAME=knob VALUE=reassignbycomponent>
459 460 461
          Reassign bug to owner ";
        if (Param("useqacontact")) { print "and QA contact "; }
        print "of selected component<br>\n";
462 463 464
        if ($status eq $::unconfirmedstate && ($canconfirm || $canedit)) {
            print "&nbsp;&nbsp;&nbsp;&nbsp;<INPUT TYPE=checkbox NAME=compconfirm> and confirm bug (change status to <b>NEW</b>)<BR>";
        }
465
        $knum++;
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481
    } 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++;
          }
        }
482 483
    } else {
        print "<INPUT TYPE=radio NAME=knob VALUE=reopen> Reopen bug<br>\n";
484
        $knum++;
485 486 487 488 489 490 491 492 493 494
        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++;
        }
495 496 497 498 499 500
    }
}
 
print "
<INPUT TYPE=\"submit\" VALUE=\"Commit\">
<INPUT TYPE=\"reset\" VALUE=\"Reset\">
501
<INPUT TYPE=\"hidden\" name=\"form_name\" VALUE=\"process_bug\">
502
<P>
503
<FONT size=\"+1\"><B>
504
 <A HREF=\"show_activity.cgi?id=$id\">View Bug Activity</A>
505
 &nbsp; | &nbsp;
506
 <A HREF=\"long_list.cgi?buglist=$id\">Format For Printing</A>
507
</B></FONT>
508 509 510
";

if ( Param("move-enabled") && (defined $::COOKIE{"Bugzilla_login"}) && ($::COOKIE{"Bugzilla_login"} =~ /($movers)/) ){
511 512 513
  print "&nbsp; <FONT size=\"+1\"><B> | </B></FONT> &nbsp;"
       ."<INPUT TYPE=\"SUBMIT\" NAME=\"action\" VALUE=\"" 
       . Param("move-button-text") . "\">\n";
514 515
}

516
print "<BR></FORM>";
517 518

print "
519 520
<table><tr><td align=left><B>Description:</B></td>
<td align=right width=100%>Opened: $bug{'creation_ts'}</td></tr></table>
521
<HR>
522
";
523
print $bug{'long_desc'};
524
print "
525 526 527 528
<HR>\n";

# To add back option of editing the long description, insert after the above
# long_list.cgi line:
529
#  <A HREF=\"edit_desc.cgi?id=$id\">Edit Long Description</A>
530 531 532

navigation_header();

533 534
PutFooter();

535
1;