diff options
Diffstat (limited to 'editproducts.cgi')
-rwxr-xr-x | editproducts.cgi | 539 |
1 files changed, 527 insertions, 12 deletions
diff --git a/editproducts.cgi b/editproducts.cgi index 5649c4440..675a70d9e 100755 --- a/editproducts.cgi +++ b/editproducts.cgi @@ -29,7 +29,8 @@ use strict; use lib "."; - +use vars qw ($template $vars); +use Bugzilla::Constants; require "CGI.pl"; require "globals.pl"; @@ -38,9 +39,16 @@ require "globals.pl"; sub sillyness { my $zz; + $zz = %::MFORM; $zz = $::unconfirmedstate; } +my %ctl = ( + &::CONTROLMAPNA => 'NA', + &::CONTROLMAPSHOWN => 'Shown', + &::CONTROLMAPDEFAULT => 'Default', + &::CONTROLMAPMANDATORY => 'Mandatory' +); # TestProduct: just returns if the specified product does exists # CheckProduct: same check, optionally emit an error text @@ -187,10 +195,9 @@ unless (UserInGroup("editcomponents")) { # my $product = trim($::FORM{product} || ''); my $action = trim($::FORM{action} || ''); +my $headerdone = 0; my $localtrailer = "<A HREF=\"editproducts.cgi\">edit</A> more products"; - - # # action='' -> Show nice list of products # @@ -342,7 +349,7 @@ if ($action eq 'new') { # If we're using bug groups, then we need to create a group for this # product as well. -JMR, 2/16/00 - if(Param("usebuggroups")) { + if(Param("makeproductgroups")) { # Next we insert into the groups table SendSQL("INSERT INTO groups " . "(name, description, isbuggroup, last_changed) " . @@ -356,6 +363,35 @@ if ($action eq 'new') { VALUES ($admin, $gid, 0)"); SendSQL("INSERT INTO group_group_map (member_id, grantor_id, isbless) VALUES ($admin, $gid, 1)"); + + # Associate the new group and new product. + SendSQL("INSERT INTO group_control_map " . + "(group_id, product_id, entry, " . + "membercontrol, othercontrol, canedit) VALUES " . + "($gid, $product_id, " . Param("useentrygroupdefault") . + ", " . CONTROLMAPDEFAULT . ", " . + CONTROLMAPNA . ", 0)"); + + # Permit the new product to use any non-product bug groups. + SendSQL("SELECT groups.id, products.id IS NULL FROM groups " . + "LEFT JOIN products " . + "ON groups.name = products.name " . + "WHERE isactive != 0 AND isbuggroup != 0 "); + while (MoreSQLData()) { + my ($grpid, $nonproductgroup) = FetchSQLData(); + if ($nonproductgroup) { + PushGlobalSQLState(); + SendSQL("INSERT INTO group_control_map " . + "(group_id, product_id, entry, " . + "membercontrol, othercontrol, canedit) VALUES " . + "entry, control, canedit) VALUES " . + "($grpid, $product_id, 0, " . + CONTROLMAPSHOWN . ", " . + CONTROLMAPNA . ", 0)"); + PopGlobalSQLState(); + } + } + } @@ -510,7 +546,7 @@ one."; print "<INPUT TYPE=SUBMIT VALUE=\"Yes, delete\">\n"; print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"delete\">\n"; print "<INPUT TYPE=HIDDEN NAME=\"product\" VALUE=\"" . - value_quote($product) . "\">\n"; + html_quote($product) . "\">\n"; print "</FORM>"; PutTrailer($localtrailer); @@ -538,6 +574,7 @@ if ($action eq 'delete') { versions WRITE, products WRITE, groups WRITE, + group_control_map WRITE, profiles WRITE, milestones WRITE, flaginclusions WRITE, @@ -583,6 +620,10 @@ if ($action eq 'delete') { WHERE product_id=$product_id"); print "Milestones deleted.<BR>\n"; + SendSQL("DELETE FROM group_control_map + WHERE product_id=$product_id"); + print "Group controls deleted.<BR>\n"; + SendSQL("DELETE FROM flaginclusions WHERE product_id=$product_id"); SendSQL("DELETE FROM flagexclusions @@ -593,7 +634,6 @@ if ($action eq 'delete') { WHERE id=$product_id"); print "Product '$product' deleted.<BR>\n"; - SendSQL("UNLOCK TABLES"); unlink "data/versioncache"; @@ -693,6 +733,27 @@ if ($action eq 'edit') { } print "</TD>\n</TR><TR>\n"; + print " <TH ALIGN=\"right\" VALIGN=\"top\"><A HREF=\"editproducts.cgi?action=editgroupcontrols&product=", url_quote($product), "\">Edit Group Access Controls</A></TH>\n"; + print "<TD>\n"; + SendSQL("SELECT id, name, isactive, entry, membercontrol, othercontrol, canedit " . + "FROM groups, " . + "group_control_map " . + "WHERE group_control_map.group_id = id AND product_id = $product_id " . + "AND isbuggroup != 0 ORDER BY name"); + while (MoreSQLData()) { + my ($id, $name, $isactive, $entry, $membercontrol, $othercontrol, $canedit) + = FetchSQLData(); + print "<B>" . html_quote($name) . ":</B> "; + if ($isactive) { + print $ctl{$membercontrol} . "/" . $ctl{$othercontrol}; + print ", ENTRY" if $entry; + print ", CANEDIT" if $canedit; + } else { + print "DISABLED"; + } + print "<BR>\n"; + } + print "</TD>\n</TR><TR>\n"; print " <TH ALIGN=\"right\">Bugs:</TH>\n"; print " <TD>"; SendSQL("SELECT count(bug_id),product_id @@ -706,11 +767,11 @@ if ($action eq 'edit') { print "</TD>\n</TR></TABLE>\n"; print "<INPUT TYPE=HIDDEN NAME=\"productold\" VALUE=\"" . - value_quote($product) . "\">\n"; + html_quote($product) . "\">\n"; print "<INPUT TYPE=HIDDEN NAME=\"descriptionold\" VALUE=\"" . - value_quote($description) . "\">\n"; + html_quote($description) . "\">\n"; print "<INPUT TYPE=HIDDEN NAME=\"milestoneurlold\" VALUE=\"" . - value_quote($milestoneurl) . "\">\n"; + html_quote($milestoneurl) . "\">\n"; print "<INPUT TYPE=HIDDEN NAME=\"disallownewold\" VALUE=\"$disallownew\">\n"; print "<INPUT TYPE=HIDDEN NAME=\"votesperuserold\" VALUE=\"$votesperuser\">\n"; print "<INPUT TYPE=HIDDEN NAME=\"maxvotesperbugold\" VALUE=\"$maxvotesperbug\">\n"; @@ -729,6 +790,230 @@ if ($action eq 'edit') { } +# +# action='updategroupcontrols' -> update the product +# + +if ($action eq 'updategroupcontrols') { + my $product_id = get_product_id($product); + my @now_na = (); + my @now_mandatory = (); + foreach my $f (keys %::FORM) { + if ($f =~ /^membercontrol_(\d+)$/) { + my $id = $1; + if ($::FORM{$f} == CONTROLMAPNA) { + push @now_na,$id; + } elsif ($::FORM{$f} == CONTROLMAPMANDATORY) { + push @now_mandatory,$id; + } + } + } + if (!($::FORM{'confirmed'})) { + $vars->{'form'} = \%::FORM; + $vars->{'mform'} = \%::MFORM; + my @na_groups = (); + if (@now_na) { + SendSQL("SELECT groups.name, COUNT(bugs.bug_id) + FROM bugs, bug_group_map, groups + WHERE groups.id IN(" . join(',',@now_na) . ") + AND bug_group_map.group_id = groups.id + AND bug_group_map.bug_id = bugs.bug_id + AND bugs.product_id = $product_id + GROUP BY groups.name"); + while (MoreSQLData()) { + my ($groupname, $bugcount) = FetchSQLData(); + my %g = (); + $g{'name'} = $groupname; + $g{'count'} = $bugcount; + push @na_groups,\%g; + } + } + + my @mandatory_groups = (); + if (@now_mandatory) { + SendSQL("SELECT groups.name, COUNT(bugs.bug_id) + FROM bugs, groups + LEFT JOIN bug_group_map + ON bug_group_map.group_id = groups.id + AND bug_group_map.bug_id = bugs.bug_id + WHERE groups.id IN(" . join(',',@now_mandatory) . ") + AND bugs.product_id = $product_id + AND bug_group_map.bug_id IS NULL + GROUP BY groups.name"); + while (MoreSQLData()) { + my ($groupname, $bugcount) = FetchSQLData(); + my %g = (); + $g{'name'} = $groupname; + $g{'count'} = $bugcount; + push @mandatory_groups,\%g; + } + } + if ((@na_groups) || (@mandatory_groups)) { + $vars->{'product'} = $product; + $vars->{'na_groups'} = \@na_groups; + $vars->{'mandatory_groups'} = \@mandatory_groups; + $template->process("admin/products/groupcontrol/confirm-edit.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + exit; + } + } + PutHeader("Update group access controls for product \"$product\""); + $headerdone = 1; + SendSQL("SELECT id, name FROM groups " . + "WHERE isbuggroup != 0 AND isactive != 0"); + while (MoreSQLData()){ + my ($groupid, $groupname) = FetchSQLData(); + my $newmembercontrol = $::FORM{"membercontrol_$groupid"} || 0; + my $newothercontrol = $::FORM{"othercontrol_$groupid"} || 0; + # Legality of control combination is a function of + # membercontrol\othercontrol + # NA SH DE MA + # NA + - - - + # SH + + + + + # DE + - + + + # MA - - - + + unless (($newmembercontrol == $newothercontrol) + || ($newmembercontrol == CONTROLMAPSHOWN) + || (($newmembercontrol == CONTROLMAPDEFAULT) + && ($newothercontrol != CONTROLMAPSHOWN))) { + ThrowUserError('illegal_group_control_combination', + {groupname => $groupname, + header_done => 1}); + } + } + SendSQL("LOCK TABLES groups READ, + group_control_map WRITE, + bugs WRITE, + bugs_activity WRITE, + bug_group_map WRITE, + fielddefs READ"); + SendSQL("SELECT id, name, entry, membercontrol, othercontrol, canedit " . + "FROM groups " . + "LEFT JOIN group_control_map " . + "ON group_control_map.group_id = id AND product_id = $product_id " . + "WHERE isbuggroup != 0 AND isactive != 0"); + while (MoreSQLData()) { + my ($groupid, $groupname, $entry, $membercontrol, + $othercontrol, $canedit) = FetchSQLData(); + my $newentry = $::FORM{"entry_$groupid"} || 0; + my $newmembercontrol = $::FORM{"membercontrol_$groupid"} || 0; + my $newothercontrol = $::FORM{"othercontrol_$groupid"} || 0; + my $newcanedit = $::FORM{"canedit_$groupid"} || 0; + my $oldentry = $entry; + $entry = $entry || 0; + $membercontrol = $membercontrol || 0; + $othercontrol = $othercontrol || 0; + $canedit = $canedit || 0; + detaint_natural($newentry); + detaint_natural($newothercontrol); + detaint_natural($newmembercontrol); + detaint_natural($newcanedit); + if ((!defined($oldentry)) && + (($newentry) || ($newmembercontrol) || ($newcanedit))) { + PushGlobalSQLState(); + SendSQL("INSERT INTO group_control_map " . + "(group_id, product_id, entry, " . + "membercontrol, othercontrol, canedit) " . + "VALUES " . + "($groupid, $product_id, $newentry, " . + "$newmembercontrol, $newothercontrol, $newcanedit)"); + PopGlobalSQLState(); + } elsif (($newentry != $entry) + || ($newmembercontrol != $membercontrol) + || ($newothercontrol != $othercontrol) + || ($newcanedit != $canedit)) { + PushGlobalSQLState(); + SendSQL("UPDATE group_control_map " . + "SET entry = $newentry, " . + "membercontrol = $newmembercontrol, " . + "othercontrol = $newothercontrol, " . + "canedit = $newcanedit " . + "WHERE group_id = $groupid " . + "AND product_id = $product_id"); + PopGlobalSQLState(); + } + + if (($newentry == 0) && ($newmembercontrol == 0) + && ($newothercontrol == 0) && ($newcanedit == 0)) { + PushGlobalSQLState(); + SendSQL("DELETE FROM group_control_map " . + "WHERE group_id = $groupid " . + "AND product_id = $product_id"); + PopGlobalSQLState(); + } + } + + foreach my $groupid (@now_na) { + print "Removing bugs from NA group " + . html_quote(GroupIdToName($groupid)) . "<P>\n"; + my $count = 0; + SendSQL("SELECT bugs.bug_id, + (lastdiffed >= delta_ts) + FROM bugs, bug_group_map + WHERE group_id = $groupid + AND bug_group_map.bug_id = bugs.bug_id + AND bugs.product_id = $product_id + ORDER BY bugs.bug_id"); + while (MoreSQLData()) { + my ($bugid, $mailiscurrent) = FetchSQLData(); + PushGlobalSQLState(); + SendSQL("DELETE FROM bug_group_map WHERE + bug_id = $bugid AND group_id = $groupid"); + SendSQL("SELECT name, NOW() FROM groups WHERE id = $groupid"); + my ($removed, $timestamp) = FetchSQLData(); + LogActivityEntry($bugid, "bug_group", $removed, "", + $::userid, $timestamp); + if ($mailiscurrent != 0) { + SendSQL("UPDATE bugs SET lastdiffed = " . SqlQuote($timestamp) + . " WHERE bug_id = $bugid"); + } + SendSQL("UPDATE bugs SET delta_ts = " . SqlQuote($timestamp) + . " WHERE bug_id = $bugid"); + PopGlobalSQLState(); + $count++; + } + print "dropped $count bugs<p>\n"; + } + + foreach my $groupid (@now_mandatory) { + print "Adding bugs to Mandatory group " + . html_quote(GroupIdToName($groupid)) . "<P>\n"; + my $count = 0; + SendSQL("SELECT bugs.bug_id, + (lastdiffed >= delta_ts) + FROM bugs + LEFT JOIN bug_group_map + ON bug_group_map.bug_id = bugs.bug_id + AND group_id = $groupid + WHERE bugs.product_id = $product_id + AND bug_group_map.bug_id IS NULL + ORDER BY bugs.bug_id"); + while (MoreSQLData()) { + my ($bugid, $mailiscurrent) = FetchSQLData(); + PushGlobalSQLState(); + SendSQL("INSERT INTO bug_group_map (bug_id, group_id) + VALUES ($bugid, $groupid)"); + SendSQL("SELECT name, NOW() FROM groups WHERE id = $groupid"); + my ($added, $timestamp) = FetchSQLData(); + LogActivityEntry($bugid, "bug_group", "", $added, + $::userid, $timestamp); + if ($mailiscurrent != 0) { + SendSQL("UPDATE bugs SET lastdiffed = " . SqlQuote($timestamp) + . " WHERE bug_id = $bugid"); + } + SendSQL("UPDATE bugs SET delta_ts = " . SqlQuote($timestamp) + . " WHERE bug_id = $bugid"); + PopGlobalSQLState(); + $count++; + } + print "added $count bugs<p>\n"; + } + SendSQL("UNLOCK TABLES"); + print "Group control updates done<P>\n"; + + PutTrailer($localtrailer); + exit; +} # # action='update' -> update the product @@ -770,6 +1055,7 @@ if ($action eq 'update') { SendSQL("LOCK TABLES products WRITE, versions READ, groups WRITE, + group_control_map WRITE, profiles WRITE, milestones READ"); @@ -863,9 +1149,9 @@ if ($action eq 'update') { } SendSQL("UPDATE products SET name=$qp WHERE id=$product_id"); - # Need to do an update to groups as well. If there is a corresponding - # bug group, whether usebuggroups is currently set or not, we want to - # update it so it will match in the future. If there is no group, this + # Need to do an update to groups as well. If there is + # a corresponding bug group, we want to update it so it will + # match in the future. If there is no group, this # update statement will do nothing, so no harm done. -JMR, 3/8/00 SendSQL("UPDATE groups " . "SET name = $qp, " . @@ -945,6 +1231,235 @@ if ($action eq 'update') { exit; } +# +# action='editgroupcontrols' -> update product group controls +# + +if ($action eq 'editgroupcontrols') { + my $product_id = get_product_id($product); + # Display a group if it is either enabled or has bugs for this product. + SendSQL("SELECT id, name, entry, membercontrol, othercontrol, canedit, " . + "isactive, COUNT(bugs.bug_id) " . + "FROM groups " . + "LEFT JOIN group_control_map " . + "ON group_control_map.group_id = id " . + "AND group_control_map.product_id = $product_id " . + "LEFT JOIN bug_group_map " . + "ON bug_group_map.group_id = groups.id " . + "LEFT JOIN bugs " . + "ON bugs.bug_id = bug_group_map.bug_id " . + "AND bugs.product_id = $product_id " . + "WHERE isbuggroup != 0 " . + "AND (isactive != 0 OR entry IS NOT NULL " . + "OR bugs.bug_id IS NOT NULL) " . + "GROUP BY name"); + my @groups = (); + while (MoreSQLData()) { + my %group = (); + my ($groupid, $groupname, $entry, $membercontrol, $othercontrol, + $canedit, $isactive, $bugcount) = FetchSQLData(); + $group{'id'} = $groupid; + $group{'name'} = $groupname; + $group{'entry'} = $entry; + $group{'membercontrol'} = $membercontrol; + $group{'othercontrol'} = $othercontrol; + $group{'canedit'} = $canedit; + $group{'isactive'} = $isactive; + $group{'bugcount'} = $bugcount; + push @groups,\%group; + } + $vars->{'header_done'} = $headerdone; + $vars->{'product'} = $product; + $vars->{'groups'} = \@groups; + $vars->{'const'} = { + 'CONTROLMAPNA' => CONTROLMAPNA, + 'CONTROLMAPSHOWN' => CONTROLMAPSHOWN, + 'CONTROLMAPDEFAULT' => CONTROLMAPDEFAULT, + 'CONTROLMAPMANDATORY' => CONTROLMAPMANDATORY, + }; + + $template->process("admin/products/groupcontrol/edit.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + exit; + + print "<!-- \n"; + print "<script type=\"text/javascript\">\n"; + print "function hide(id) {\n"; + print " id.visibility = 0\n"; + print " alert(id)\n"; + print "}\n"; + print "</script>"; + print " -->\n"; + print "<STYLE type=\"text/css\">\n"; + print " .hstyle { visibility: visible; color: red; }\n"; + print "</STYLE>\n"; + print "<FORM METHOD=POST ACTION=editproducts.cgi>\n"; + print "<TABLE BORDER=1 CELLPADDING=4 CELLSPACING=0><TR BGCOLOR=\"#6666FF\">\n"; + print " <TH ALIGN=\"left\">Group</TH>\n"; + print " <TH ALIGN=\"left\">Entry</TH>\n"; + print " <TH ALIGN=\"left\">MemberControl</TH>\n"; + print " <TH ALIGN=\"left\">OtherControl</TH>\n"; + print " <TH ALIGN=\"left\">Canedit</TH>\n"; + while (MoreSQLData()) { + print "</TR>\n"; + my ($groupid, $groupname, $entry, $membercontrol, $othercontrol, + $canedit) = FetchSQLData(); + print "<TR id=\"row_$groupname\" class=\"hstyle\" "; + print "onload=\"document.row.row_$groupname.color=green\">\n"; + print " <TD>\n"; + print " $groupname\n"; + print " </TD><TD>\n"; + $entry |= 0; + print " <INPUT TYPE=CHECKBOX NAME=\"entry_$groupid\" VALUE=1"; + print " CHECKED " if $entry; + print ">\n"; + print " </TD><TD>\n"; + $membercontrol |= 0; + $othercontrol |= 0; + print " <SELECT NAME=\"membercontrol_$groupid\">\n"; + print " <OPTION VALUE=" . CONTROLMAPNA; + print " selected=\"selected\"" if ($membercontrol == CONTROLMAPNA); + print ">NA</OPTION>\n"; + print " <OPTION VALUE=" . CONTROLMAPSHOWN; + print " selected=\"selected\"" if ($membercontrol == CONTROLMAPSHOWN); + print ">Shown</OPTION>\n"; + print " <OPTION VALUE=" . CONTROLMAPDEFAULT; + print " selected=\"selected\"" if ($membercontrol == CONTROLMAPDEFAULT); + print ">Default</OPTION>\n"; + print " <OPTION VALUE=" . CONTROLMAPMANDATORY; + print " selected=\"selected\"" if ($membercontrol == CONTROLMAPMANDATORY); + print ">Mandatory</OPTION>\n"; + print "</SELECT>\n"; + print " </TD><TD>\n"; + print " <SELECT NAME=\"othercontrol_$groupid\">\n"; + print " <OPTION VALUE=" . CONTROLMAPNA; + print " selected=\"selected\"" if ($othercontrol == CONTROLMAPNA); + print ">NA</OPTION>\n"; + print " <OPTION VALUE=" . CONTROLMAPSHOWN; + print " selected=\"selected\"" if ($othercontrol == CONTROLMAPSHOWN); + print ">Shown</OPTION>\n"; + print " <OPTION VALUE=" . CONTROLMAPDEFAULT; + print " selected=\"selected\"" if ($othercontrol == CONTROLMAPDEFAULT); + print ">Default</OPTION>\n"; + print " <OPTION VALUE=" . CONTROLMAPMANDATORY; + print " selected=\"selected\"" if ($othercontrol == CONTROLMAPMANDATORY); + print ">Mandatory</OPTION>\n"; + print "</SELECT>\n"; + print " </TD><TD>\n"; + $canedit |= 0; + print " <INPUT TYPE=CHECKBOX NAME=\"canedit_$groupid\" VALUE=1"; + print " CHECKED " if $canedit; + print ">\n"; + + } + + print "</TR>\n"; + print "</TABLE><BR>"; + print "Add controls to the panel above:<BR>\n"; + print "<SELECT NAME=\"newgroups\" SIZE=\"10\" MULTIPLE=\"MULTIPLE\">\n"; + SendSQL("SELECT id, name " . + "FROM groups " . + "LEFT JOIN group_control_map " . + "ON group_control_map.group_id = id AND product_id = $product_id " . + "WHERE canedit IS NULL AND isbuggroup != 0 AND isactive != 0 " . + "ORDER BY name"); + while (MoreSQLData()) { + my ($groupid, $groupname) = FetchSQLData(); + print "<OPTION VALUE=\"$groupid\">$groupname</OPTION>\n"; + } + print "</SELECT><BR><BR>\n"; + + print "<INPUT TYPE=SUBMIT VALUE=\"Update\">\n"; + print "<INPUT TYPE=RESET>\n"; + print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"updategroupcontrols\">\n"; + print "<INPUT TYPE=HIDDEN NAME=\"product\" VALUE=\"$product\">\n"; + print "</FORM>\n"; + print "<P>note: Any group controls Set to NA/NA with no other checkboxes "; + print "will automatically be removed from the panel the next time "; + print "update is clicked.\n"; + print "<P>These settings control the relationship of the groups to this "; + print "product.\n"; + print "<P>If any group has <B>Entry</B> selected, then this product will "; + print "restrict bug entry to only those users who are members of all the "; + print "groups with entry selected.\n"; + print "<P>If any group has <B>Canedit</B> selected, then this product "; + print "will be read-only for any users who are not members of all of "; + print "the groups with Canedit selected. ONLY users who are members of "; + print "all the canedit groups will be able to edit. This is an additional "; + print "restriction that further restricts what can be edited by a user.\n"; + print "<P>The <B>MemberControl</B> and <B>OtherControl</B> fields "; + print "indicate which bugs will be placed in "; + print "this group according to the following definitions.\n"; + print "<BR><TABLE BORDER=1>"; + print "<TR>"; + print "<TH>MemberControl</TH><TH>OtherControl</TH><TH>Interpretation</TH>"; + print "</TR><TR>"; + print "<TD>NA</TD>\n"; + print "<TD>NA</TD>\n"; + print "<TD>Bugs in this product are never associated with this group.</TD>\n"; + print "</TR><TR>"; + print "<TD>Shown</TD>\n"; + print "<TD>NA</TD>\n"; + print "<TD>Bugs in this product are permitted to be restricted to this "; + print "group. Users who are a member of this group will be able "; + print "to place bugs in this group.</TD>\n"; + print "</TR><TR>"; + print "<TD>Shown</TD>\n"; + print "<TD>Shown</TD>\n"; + print "<TD>Bugs in this product can be placed in this group by anyone "; + print "with permission to edit the bug even if they are not a member "; + print "of this group.</TD>\n"; + print "</TR><TR>"; + print "<TD>Shown</TD>\n"; + print "<TD>Default</TD>\n"; + print "<TD>Bugs in this product can be placed in this group by anyone "; + print "with permission to edit the bug even if they are not a member "; + print "of this group. Non-members place bugs in this group by default."; + print "</TD>\n"; + print "</TR><TR>"; + print "<TD>Shown</TD>\n"; + print "<TD>Mandatory</TD>\n"; + print "<TD>Bugs in this product are permitted to be restricted to this "; + print "group. Users who are a member of this group will be able "; + print "to place bugs in this group."; + print "Non-members will be forced to restrict bugs to this group "; + print "when they initially enter a bug in this product."; + print "</TD>\n"; + print "</TR><TR>"; + print "<TD>Default</TD>\n"; + print "<TD>NA</TD>\n"; + print "<TD>Bugs in this product are permitted to be restricted to this "; + print "group and are placed in this group by default."; + print "Users who are a member of this group will be able "; + print "to place bugs in this group.</TD>\n"; + print "</TR><TR>"; + print "<TD>Default</TD>\n"; + print "<TD>Default</TD>\n"; + print "<TD>Bugs in this product are permitted to be restricted to this "; + print "group and are placed in this group by default."; + print "Users who are a member of this group will be able "; + print "to place bugs in this group. Non-members will be able to "; + print "restrict bugs to this group on entry and will do so by default "; + print "</TD>\n"; + print "</TR><TR>"; + print "<TD>Default</TD>\n"; + print "<TD>Mandatory</TD>\n"; + print "<TD>Bugs in this product are permitted to be restricted to this "; + print "group and are placed in this group by default."; + print "Users who are a member of this group will be able "; + print "to place bugs in this group. Non-members will be forced "; + print "to place bugs in this group on entry."; + print "</TR><TR>"; + print "<TD>Mandatory</TD>\n"; + print "<TD>Mandatory</TD>\n"; + print "<TD>Bugs in this product are required to be restricted to this "; + print "group. Users are not given any option.</TD>\n"; + print "</TABLE>"; + + + PutTrailer($localtrailer); + exit; +} # |