summaryrefslogtreecommitdiffstats
path: root/editproducts.cgi
diff options
context:
space:
mode:
authorbugreport%peshkin.net <>2002-11-25 04:56:17 +0100
committerbugreport%peshkin.net <>2002-11-25 04:56:17 +0100
commitc64d51111a5ae02d6fc45163a847d0b7e2004548 (patch)
treefd7a0cb912e4411573faa5305df4d4971a3b6dda /editproducts.cgi
parente7720dcdd4e332c096a310c53412d3acaacd381e (diff)
downloadbugzilla-c64d51111a5ae02d6fc45163a847d0b7e2004548.tar.gz
bugzilla-c64d51111a5ae02d6fc45163a847d0b7e2004548.tar.xz
Bug 147275 Rearchitect product groups
Patch by joel r=bbaetz,justdave a=justdave
Diffstat (limited to 'editproducts.cgi')
-rwxr-xr-xeditproducts.cgi539
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;
+}
#