diff --git a/mozilla/webtools/bugzilla/globals.pl b/mozilla/webtools/bugzilla/globals.pl index 51fe1ddee4a..29024e26da1 100644 --- a/mozilla/webtools/bugzilla/globals.pl +++ b/mozilla/webtools/bugzilla/globals.pl @@ -1108,6 +1108,16 @@ sub UserInGroup { return 0; } +sub BugInGroup { + my ($bugid, $groupname) = (@_); + my $groupbit = GroupNameToBit($groupname); + PushGlobalSQLState(); + SendSQL("SELECT (bugs.groupset & $groupbit) != 0 FROM bugs WHERE bugs.bug_id = $bugid"); + my $bugingroup = FetchOneColumn(); + PopGlobalSQLState(); + return $bugingroup; +} + sub GroupExists { my ($groupname) = (@_); ConnectToDatabase(); @@ -1116,11 +1126,25 @@ sub GroupExists { return $count; } +# Given the name of an existing group, returns the bit associated with it. +# If the group does not exist, returns 0. +# !!! Remove this function when the new group system is implemented! +sub GroupNameToBit { + my ($groupname) = (@_); + ConnectToDatabase(); + PushGlobalSQLState(); + SendSQL("SELECT bit FROM groups WHERE name = " . SqlQuote($groupname)); + my $bit = FetchOneColumn() || 0; + PopGlobalSQLState(); + return $bit; +} + # Determines whether or not a group is active by checking # the "isactive" column for the group in the "groups" table. # Note: This function selects groups by bit rather than by name. sub GroupIsActive { my ($groupbit) = (@_); + $groupbit ||= 0; ConnectToDatabase(); SendSQL("select isactive from groups where bit=$groupbit"); my $isactive = FetchOneColumn(); diff --git a/mozilla/webtools/bugzilla/process_bug.cgi b/mozilla/webtools/bugzilla/process_bug.cgi index d42f6b84eb8..51115091134 100755 --- a/mozilla/webtools/bugzilla/process_bug.cgi +++ b/mozilla/webtools/bugzilla/process_bug.cgi @@ -108,7 +108,19 @@ if ( Param("strictvaluechecks") ) { } } -if ($::FORM{'product'} ne $::dontchange) { +ConnectToDatabase(); + +# Figure out whether or not the user is trying to change the product +# (either the "product" variable is not set to "don't change" or the +# user is changing a single bug and has changed the bug's product), +# and make the user verify the version, component, target milestone, +# and bug groups if so. +if ( $::FORM{'id'} ) { + SendSQL("SELECT product FROM bugs WHERE bug_id = $::FORM{'id'}"); + $::oldproduct = FetchSQLData(); +} +if ( ($::FORM{'id'} && $::FORM{'product'} ne $::oldproduct) + || (!$::FORM{'id'} && $::FORM{'product'} ne $::dontchange) ) { if ( Param("strictvaluechecks") ) { CheckFormField(\%::FORM, 'product', \@::legal_product); } @@ -130,42 +142,105 @@ if ($::FORM{'product'} ne $::dontchange) { $mok = lsearch($::target_milestone{$prod}, $::FORM{'target_milestone'}) >= 0; } - if (!$vok || !$cok || !$mok) { - print "
\n"; - print "
\n"; - print "\n"; - print "Cancel all this and go to the query page.\n"; + + # Display UI for verifying the version, component, and target milestone fields. + if (!$vok || !$cok || !$mok) { + my ($sectiontitle, $sectiondescription); + if ( Param('usetargetmilestone') ) { + $sectiontitle = "Verify Version, Component, Target Milestone"; + $sectiondescription = qq| + You are moving the bug(s) to the product $prod, and now the + version, component, and/or target milestone fields are not correct + (or perhaps they were not correct in the first place). In any case, + please set the correct version, component, and target milestone now: + |; + } else { + $sectiontitle = "Verify Version, Component"; + $sectiondescription = qq| + You are moving the bug(s) to the product $prod, and now the + version, and component fields are not correct (or perhaps they were + not correct in the first place). In any case, please set the correct + version and component now: + |; + } + + my $versionmenu = Version_element($::FORM{'version'}, $prod); + my $componentmenu = Component_element($::FORM{'component'}, $prod); + + print qq| ++ $sectiondescription +
+ +
|
+ Version: + $versionmenu + |
+
+ Component: + $componentmenu + |
+ |;
+
+ if ( Param("usetargetmilestone") ) {
+ my $milestonemenu = Milestone_element($::FORM{'target_milestone'}, $prod);
+ print qq|
+
+ Target Milestone: + $milestonemenu + |
+ |;
+ }
+
+ print qq|
+
+ Do you want to add the bug to its new product's group (if any)? +
+ +
+ no
+ yes
+
+ yes, but only if the bug was in its old product's group
+
\n|;
+ print qq|usebuggroups is enabled and this bug has changed from the
+ $oldhash{'product'} to the $::FORM{'product'} product,
+ so it is time to check if we have to remove the bug from its old product
+ group or add it to its new product group.
\n|;
+ # END DEBUGGING INSTRUCTIONS THAT WILL GO AWAY ONCE THIS PATCH IS READY
+ if (
+ # the user wants to add the bug to the new product's group;
+ ($::FORM{'addtonewgroup'} eq 'yes'
+ || ($::FORM{'addtonewgroup'} eq 'yesifinold'
+ && GroupNameToBit($oldhash{'product'}) & $oldhash{'groupset'}))
+
+ # the new product is associated with a group;
+ && GroupExists($::FORM{'product'})
+
+ # the bug is not already in the group; (This can happen when the user
+ # goes to the "edit multiple bugs" form with a list of bugs at least
+ # one of which is in the new group. In this situation, the user can
+ # simultaneously change the bugs to a new product and move the bugs
+ # into that product's group, which happens earlier in this script
+ # and thus is already done. If we didn't check for this, then this
+ # situation would cause us to add the bug to the group twice, which
+ # would result in the bug being added to a totally different group.)
+ && !BugInGroup($id, $::FORM{'product'})
+
+ # the user is a member of the associated group, indicating they
+ # are authorized to add bugs to that group, *or* the "usebuggroupsentry"
+ # parameter is off, indicating that users can add bugs to a product
+ # regardless of whether or not they belong to its associated group;
+ && (UserInGroup($::FORM{'product'}) || !Param('usebuggroupsentry'))
+
+ # the associated group is active, indicating it can accept new bugs;
+ && GroupIsActive(GroupNameToBit($::FORM{'product'}))
+ ) {
+ # Add the bug to the group associated with its new product.
+ my $groupbit = GroupNameToBit($::FORM{'product'});
+ # DEBUGGING INSTRUCTIONS THAT WILL GO AWAY ONCE THIS PATCH IS READY
+ print qq|
+ The user specified addtonewgroup, there is a group
+ associated with the new product, the user is a member of that
+ group (or usebuggroupsentry is off), and the group
+ is active, so we have to add the product to the group:
+ UPDATE bugs SET groupset = groupset + $groupbit WHERE bug_id = $id
+ |;
+ # END DEBUGGING INSTRUCTIONS THAT WILL GO AWAY ONCE THIS PATCH IS READY
+ SendSQL("UPDATE bugs SET groupset = groupset + $groupbit WHERE bug_id = $id");
+ }
+
+ if (
+ # the old product is associated with a group;
+ GroupExists($oldhash{'product'})
+
+ # the bug is a member of that group;
+ && BugInGroup($id, $oldhash{'product'})
+ ) {
+ # Remove the bug from the group associated with its old product.
+ # DEBUGGING INSTRUCTIONS THAT WILL GO AWAY ONCE THIS PATCH IS READY
+ my $groupbit = GroupNameToBit($oldhash{'product'});
+ print qq|
+ There is a group associated with the old product, the bug is a
+ member of that group, so remove the bug from the group:
+ UPDATE bugs SET groupset = groupset - $groupbit WHERE bug_id = $id
+ |;
+ # END DEBUGGING INSTRUCTIONS THAT WILL GO AWAY ONCE THIS PATCH IS READY
+ SendSQL("UPDATE bugs SET groupset = groupset - $groupbit WHERE bug_id = $id");
+ }
+
+ print qq|