Login
Log in using an SSO provider:
Fedora Account System
Red Hat Associate
Red Hat Customer
Login using a Red Hat Bugzilla account
Forgot Password
Create an Account
Red Hat Bugzilla – Attachment 297564 Details for
Bug 433744
Implement Bugzilla::Bug set_all, which takes parameters from a hash and does all updates in the right order
Home
New
Search
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh90 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
[?]
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Bugzlla::WebService::Bug::update()
patch.diff (text/plain), 36.30 KB, created by
Noura El hawary
on 2008-03-11 06:09:40 UTC
(
hide
)
Description:
Bugzlla::WebService::Bug::update()
Filename:
MIME Type:
Creator:
Noura El hawary
Created:
2008-03-11 06:09:40 UTC
Size:
36.30 KB
patch
obsolete
>Index: Bugzilla/WebService/Bug.pm >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/Bugzilla/WebService/Bug.pm,v >retrieving revision 1.7 >diff -p -u -r1.7 Bug.pm >--- Bugzilla/WebService/Bug.pm 11 Mar 2008 03:47:17 -0000 1.7 >+++ Bugzilla/WebService/Bug.pm 11 Mar 2008 06:00:59 -0000 >@@ -36,6 +36,7 @@ use Bugzilla::Search; > use Bugzilla::Search::Quicksearch; > use Bugzilla::Search::Saved; > use Bugzilla::Util; >+use Bugzilla::Status; > > ############# > # Constants # >@@ -536,6 +537,232 @@ sub search { > return { sql => $query, bugs => \@bugs }; > } > >+# this is a function that updates a bug: >+# it can be called as the following: >+# $call = $rpc->call( 'Bug.update', {ids => [1,2], updates => {bug_status => 'NEW', priority => 'P3'}} >+sub update { >+ >+ my ($self, $params) = @_; >+ my $user = Bugzilla->login(LOGIN_REQUIRED); >+ >+ $params->{ids} || ThrowCodeError('param_required', { param => 'ids' }); >+ my $updates = $params->{updates} || ThrowCodeError('param_required', { param => 'updates' }); >+ >+ my @ids = ref($params->{ids}) ? @{$params->{ids}} : ($params->{ids}); >+ >+ my @valid_ids; >+ foreach my $bug_id (@ids) { >+ ValidateBugID($bug_id); >+ push(@valid_ids, $bug_id); >+ } >+ >+ my @bug_objects; >+ @bug_objects = @{Bugzilla::Bug->new_from_list(\@valid_ids)}; >+ scalar(@bug_objects) || ThrowUserError("no_bugs_chosen", {action => 'modify'}); >+ >+ # For each bug, we have to check if the user can edit the bug the product >+ # is currently in, before we allow them to change anything. >+ foreach my $bug (@bug_objects) { >+ if (!Bugzilla->user->can_edit_product($bug->product_obj->id) ) { >+ ThrowUserError("product_edit_denied", >+ { product => $bug->product }); >+ } >+ } >+ >+ foreach my $bug (@bug_objects) { >+ my $args; >+ >+ if ($updates->{product}) { >+ foreach my $product_field qw(component version target_milestone) { >+ if (!$updates->{$product_field}){ >+ ThrowUserError("product_update_not_allowed"); >+ } >+ } >+ $args->{product} = $updates->{product}; >+ $args->{component} = $updates->{component}; >+ $args->{version} = $updates->{version}; >+ $args->{target_milestone} = $updates->{target_milestone}; >+ $args->{confirm_product_change} = 1; >+ $args->{other_bugs} = \@bug_objects; >+ } >+ >+ foreach my $group (@{$bug->product_obj->groups_valid}) { >+ my $gid = $group->id; >+ my $gname = $group->name; >+ if (grep {$_ =~ /$gname/ } @{$updates->{remove_group}}) { >+ push (@{$args->{remove_group}}, $gid); >+ } >+ elsif (grep {$_ =~ /$gname/ } @{$updates->{add_group}}) { >+ push (@{$args->{add_group}}, $gid); >+ } >+ } >+ >+ >+ # dependson and blocked lists should be passed as string of bug ids >+ # separated by commas to set_all >+ if (scalar @bug_objects > 1 && (defined $updates->{delete_dependson} >+ || defined $updates->{delete_blocked} >+ || defined $updates->{add_dependson} >+ || defined $updates->{add_blocked})) { >+ ThrowUserError("dependencies_not_allowed"); >+ } >+ else { >+ my %dependson_ids; >+ map { $dependson_ids{$_} = 1 } @{$bug->dependson}; >+ delete $dependson_ids{$_} foreach @{$updates->{delete_dependson}}; >+ >+ map { $dependson_ids{$_} = 1 } @{$updates->{add_dependson}}; >+ >+ $args->{dependson} = ($updates->{delete_dependson} || $updates->{add_dependson}) ? >+ join(',', keys %dependson_ids) : ''; >+ >+ my %blocked_ids; >+ map { $blocked_ids{$_} = 1 } @{$bug->blocked}; >+ delete $blocked_ids{$_} foreach @{$updates->{delete_blocked}}; >+ >+ map { $blocked_ids{$_} = 1 } @{$updates->{add_blocked}}; >+ >+ $args->{blocked} = ($updates->{delete_blocked} || $updates->{add_blocked}) ? >+ join(',', keys %blocked_ids) : ''; >+ >+ } >+ >+ foreach my $key_name (keys %{$params->{updates}}){ >+ if ($key_name =~ /keyword$/){ >+ $args->{$key_name} = join(',', @{$updates->{$key_name}}) if defined $updates->{$key_name}; >+ } >+ } >+ >+ my @custom_fields = Bugzilla->active_custom_fields; >+ >+ if ($updates->{comment} || $updates->{work_time}) { >+ $args->{comment} = $updates->{comment}; >+ $args->{work_time} = $updates->{work_time}; >+ $args->{commentprivacy} = $updates->{private}; >+ } >+ >+ my @set_fields = qw(op_sys rep_platform priority bug_severity >+ component target_milestone version >+ bug_file_loc status_whiteboard short_desc >+ deadline remaining_time estimated_time); >+ >+ push(@set_fields, 'assigned_to') if !$updates->{set_default_assignee}; >+ push(@set_fields, 'qa_contact') if !$updates->{set_default_qa_contact}; >+ >+ my %field_mapping = ( >+ bug_severity => 'severity', >+ rep_platform => 'platform', >+ short_desc => 'summary', >+ bug_file_loc => 'url', >+ ); >+ >+ foreach my $field (@set_fields) { >+ if ($updates->{$field}) { >+ my $mapped_field = $field_mapping{$field}; >+ my $field_name = $mapped_field || $field; >+ $args->{$field_name} = $updates->{$field}; >+ } >+ } >+ >+ $args->{set_default_assignee} = $updates->{set_default_assignee}; >+ $args->{set_default_qa_contact} = $updates->{set_default_qa_contact}; >+ >+ foreach my $field (@custom_fields) { >+ my $fname = $field->name; >+ $fname =~ /^cf_([a-z,_]+)/ ; >+ $args->{$fname} = $updates->{$1} if defined $updates->{$1}; >+ } >+ >+ # Certain changes can only happen on individual bugs, never on mass-changes. >+ if (scalar @bug_objects == 1) { >+ if (Bugzilla->params->{"usebugaliases"} && defined $updates->{alias}) { >+ $args->{alias} = $updates->{alias}; >+ } >+ >+ $args->{cclist_accessible} = $updates->{cclist_accessible}; >+ $args->{reporter_accessible} = $updates->{reporter_accessible}; >+ >+ # this part of the code is not really user friendly as the user needs >+ # to know the actual comment id as how it is in the longdescs table >+ # to be able to mark/unmark privacy of the comment >+ $args->{private_comment} = $updates->{private_comment}; >+ $args->{non_private_comment} = $updates->{non_private_comment}; >+ } >+ >+ $args->{add_cc} = $updates->{add_cc}; >+ $args->{remove_cc} = $updates->{delete_cc}; >+ >+ # You cannot mark bugs as duplicates when changing several bugs at once >+ # (because currently there is no way to check for duplicate loops in that >+ # situation). >+ if (scalar @bug_objects > 1 && $updates->{dupe_id}) { >+ ThrowUserError('dupe_not_allowed'); >+ } >+ >+ if (scalar @bug_objects > 1 && $updates->{alias}) { >+ ThrowUserError('alias_not_allowed'); >+ } >+ >+ # Set the status, resolution, and dupe_of (if needed). This has to be done >+ # down here, because the validity of status changes depends on other fields, >+ # such as Target Milestone. >+ if ( defined $updates->{bug_status} && ($bug->status->name ne $updates->{bug_status}) >+ && (is_open_state($updates->{bug_status})) ) { >+ $args->{knob} = $updates->{bug_status}; >+ } >+ elsif ( defined $updates->{bug_status} && ($bug->status->name ne $updates->{bug_status}) >+ && !(is_open_state($updates->{bug_status})) ) { >+ $args->{knob} = $updates->{bug_status}; >+ $args->{resolution} = $updates->{resolution}; >+ } >+ elsif ( defined $updates->{resolution} && ($bug->resolution ne $updates->{resolution}) >+ && !(is_open_state($bug->status->name)) ) { >+ $args->{knob} = 'change_resolution'; >+ $args->{resolution} = $updates->{resolution}; >+ } >+ elsif ( defined $updates->{dupe_id} ) { >+ $args->{knob} = 'duplicate'; >+ $args->{dupe_id} = $updates->{dupe_id}; >+ } >+ else { >+ $args->{knob} = 'none'; >+ } >+ >+ $bug->set_all($args); >+ } >+ >+ my $dbh = Bugzilla->dbh; >+ my %changes; >+ # Do Actual Database Updates # >+ foreach my $bug (@bug_objects) { >+ $dbh->bz_start_transaction(); >+ >+ my $timestamp = $dbh->selectrow_array(q{SELECT NOW()}); >+ my $bug_changes = $bug->update($timestamp); >+ $changes{$bug->bug_id} = [$bug_changes]; >+ >+ my $keyword_changes= $bug->update_keywords($timestamp); >+ push @{$changes{$bug->bug_id}}, {keywords => $keyword_changes} >+ if (scalar $keyword_changes->[0][0] || scalar $keyword_changes->[0][1]); >+ >+ my ($cc_removed) = $bug->update_cc($timestamp); >+ $cc_removed = [map {$_->login} @$cc_removed]; >+ push @{$changes{$bug->bug_id}}, {cc => $cc_removed} if scalar @$cc_removed; >+ >+ my ($dep_changes) = $bug->update_dependencies($timestamp); >+ push @{$changes{$bug->bug_id}}, {dependencies => $dep_changes} >+ if (scalar $dep_changes->{dependson}->[0][0] || scalar $dep_changes->{dependson}->[0][1] >+ || $dep_changes->{blocked}->[0][0] || $dep_changes->{blocked}->[0][1]); >+ >+ my $mail_results = Bugzilla::BugMail::Send($bug->bug_id, { changer => Bugzilla->user->login }); >+ push @{$changes{$bug->bug_id}}, $mail_results; >+ >+ $dbh->bz_commit_transaction(); >+ } >+ >+ return { bug_updates => \%changes }; >+} >+ > 1; > > __END__ >@@ -1029,4 +1256,239 @@ The saved search name was not found in t > > =back > >+=item C<update> B<EXPERIMENTAL> >+ >+=over >+ >+=item B<Description> >+ >+This allows you to update bug fields for one or more bugs. >+ >+=item B<Params> >+ >+=over >+ >+=item C<ids> (array), or (int) or (string) B<Optional> - An array of >+integers/strings, a single integer/string representing bug ids in the >+case of integers, and representing bug aliases in the case of strings. >+ >+=item C<updates> (hash) B<Required> - A hash containing bug fields >+and the new values it will be updated to. The hash may contain any of the following: >+B<NOTE> Some of the following items can only be updated when changing only >+single bug, those items are: C<alias>, C<add|delete_dependson>, >+C<add|delete_blocked>, C<dupe_id>, C<cclist_accessible>, C<reporter_accessible>. >+ >+ >+=over >+ >+=item C<product> (string) - The name of the new product. Please Note >+that if changing the product the C<updates> hash must contain all of the >+items C<component>, C<version>, C<target_milestone>. >+ >+=item C<component> (string) - The name of the new component. >+ >+=item C<version> (string) - The new version of the product. >+ >+=item C<target_milestone> (string) - A valid new target milestone for the >+product. >+ >+=item C<remove_group> (array) - An array of group names to be deleted from >+the bug, any group name that doesn't belong to the bug product will be >+ignored. >+ >+=item C<add_group> (array) - An array of group names to be added to the >+bug.any group name that doesn't belong to the bug product will be >+ignored. >+ >+=item C<delete_dependson> (array) - An array of dependson bug ids >+to be deleted from the current list of the bug's dependson ids. >+ >+=item C<add_dependson> (array) - An array of dependson bug ids >+to be added to the current list of the bug's dependson ids. >+ >+=item C<delete_blocked> (array) - An array of blocked bug ids >+to be deleted from the current list of the bug's blocked ids. >+ >+=item C<add_blocked> (array) - An array of blocked bug ids >+to be added to the current list of the bug's blocked ids. >+ >+=item C<add_keyword> (array) - An array of keywords to be added to the >+current list of the bug's keywords. >+ >+=item C<delete_keyword> (array) - An array of keywords to be deleted from the >+current list of the bug's keywords. >+ >+=item C<makeexact_keyword> (array) - An array of keywords that will replace >+the existing list of the bug's keywords >+ >+=item C<comment> (string) - A comment to be added to the bug. >+ >+=item C<work_time> (int) - The number of hours worked on the bug. >+Note that updating C<work_time> required providing C<comment>. >+ >+=item C<commentprivacy> (boolean) - A boolean value that indicates if >+the comment is private or not. The item is only of use when adding >+C<comment> and it is optional. >+ >+=item C<op_sys> (string) - The new operating system for the bug. >+ >+=item C<platform> (string) - New type of hardware the bug was >+experienced on. >+ >+=item C<priority> (string) - The new order the bug will be fixed >+in by the developer, compared to the developer's other bugs. >+ >+=item C<severity> (string) - The new severity of the bug. >+ >+=item C<bug_file_loc|url> (string) - The new bug file location. >+ >+=item C<status_whiteboard> (string) - New value for status whiteboard. >+ >+=item C<short_desc|summary> (string) - New bug summary. >+ >+=item C<deadline> (date) - The new deadline for fixing the bug. >+ >+=item C<remaining_time> (int) - The remaining number of hours >+to fix the bug. >+ >+=item C<estimated_time> (int) - The estimated number of hours to fix a bug. >+ >+=item C<alias> (string) - A brief new alias for the bug that can be used >+instead of a bug number when accessing this bug. Must be unique in >+all of this Bugzilla. >+ >+=item C<assigned_to> (username) - A new user to assign this bug to, if you >+don't want to set to the default assignee. >+ >+=item C<qa_contact> (username) - If this installation has QA Contacts >+enabled, you can update the QA Contact here if you don't want to set >+the component's default QA Contact. >+ >+=item C<set_default_assignee> (boolean) - A boolean value to indicate >+if want to reset the bug to its default assignee. >+ >+=item C<set_default_qa_contact> (boolean) - A boolean value to indicate >+if want to reset the bug to its default qa contact. >+ >+=item C<cclist_accessible> (boolean) - A boolean value to indicate if want >+to make the bug accessible to the cclist members. >+ >+=item C<reporter_accessible> (boolean) - A boolean value to indicate if want >+to make the bug accessible to its reporter. >+ >+=item C<add_cc> (array) - An array of usernames to add to the CC on this bug. >+ >+=item C<delete_cc> (array) - An array of usernames to remove from the CC on this bug. >+ >+=item C<status> (string) - The new status for the bug. >+ >+=item C<resolution> (string) - The new resolution of the bug. >+ >+=item C<dupe_id> (int) - The id of the bug that the current bug is a dupliacte >+of. >+ >+=item C<devel_whiteboard> (string) - It is a redhat custom field. That holds strings >+added/updated by devel group members. >+ >+=item C<qa_whiteboard> (string) - It is a redhat custom field. That holds strings >+added/updated by qa group members. >+ >+=item C<internal_whiteboard> (string) - It is a redhat custom field. That holds strings >+added/updated by internalwhiteboard group members. >+ >+=item C<cust_facing> (string) - It is a redhat custom field. Customer facing. >+ >+=item C<fixed_in> (string) - It is a redhat custom field. That holds the version >+the bug has been fixed in. >+ >+=back >+ >+=item B<Returns> >+ >+A hash with one element, C<bug_updates>. That points to a hash of all >+the updated bug ids. each bug id point to a hash tha holds tha changes that has >+been applied to the bug. >+ >+=item B<Errors> >+ >+=over >+ >+=item 50 (Param Required) >+ >+Either the C<ids> or the C<updates> param in not provided. >+ >+=item 101 (Invalid Bug ID) >+ >+The bug_id you specified doesn't exist in the database. >+ >+=item 106 (Product access Denied) >+ >+You do not have access to the product that the bug you specified >+belongs to. >+ >+=item 109 (Product Update Not Allowed) >+ >+Missing information when trying to update the bug product. >+All the following must be provided when updating the product: >+product name, component name, version ,and target_milestone. >+ >+=item 110 (Dependencies Not Allowed) >+ >+Bug dependencies updates not allowed when changing several bugs. >+ >+=item 111 (Dupe Not Allowed) >+ >+Bug dupulicate id can only be updating for single bug. >+ >+=item 112 (Alias Not Allowed) >+ >+Can not update alias when changing several bugs. >+ >+=item 113 (Comment Required) >+ >+You need to provide comment when updating bug work time. >+ >+=item 114 (No Bugs Chosen) >+ >+No bugs were chosed to update. >+ >+=item 51 (Invalid Object) >+ >+The component you specified is not valid for this Product. >+ >+=item 103 (Invalid Alias) >+ >+The alias you specified is invalid for some reason. See the error message >+for more details. >+ >+=item 104 (Invalid Bug Field) >+ >+One of the bug fields has an invalid value, or a value entered in a >+text field is too long. The error message will have more detail. >+ >+=item 105 (Invalid Component) >+ >+You didn't specify a component. >+ >+=item 106 (Invalid Product) >+ >+You specified invalid product. >+ >+=item 504 (Invalid User) >+ >+Either the QA Contact, Assignee, or CC lists have some invalid user >+in them. The error message will have more details. >+ >+=item 108 (Bug Edit Denied) >+ >+You did not have the necessary rights to edit the bug. >+ >+=back >+ >+=back >+ >+=back >+ > =back >+ >+ >Index: Bugzilla/WebService/Constants.pm >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/Bugzilla/WebService/Constants.pm,v >retrieving revision 1.10 >diff -p -u -r1.10 Constants.pm >--- Bugzilla/WebService/Constants.pm 11 Mar 2008 03:47:17 -0000 1.10 >+++ Bugzilla/WebService/Constants.pm 11 Mar 2008 06:01:13 -0000 >@@ -60,6 +60,12 @@ use constant WS_ERROR_CODE => { > bug_access_denied => 102, > bug_access_query => 102, > invalid_field_name => 108, >+ product_update_not_allowed => 109, >+ dependencies_not_allowed => 110, >+ dupe_not_allowed => 111, >+ alias_not_allowed => 112, >+ comment_required => 113, >+ no_bugs_chosen => 114, > # These all mean "invalid alias" > alias_too_long => 103, > alias_in_use => 103, >Index: process_bug.cgi >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/process_bug.cgi,v >retrieving revision 1.18 >diff -p -u -r1.18 process_bug.cgi >--- process_bug.cgi 5 Mar 2008 21:41:51 -0000 1.18 >+++ process_bug.cgi 11 Mar 2008 06:01:27 -0000 >@@ -65,6 +65,7 @@ use Storable qw(dclone); > my $user = Bugzilla->login(LOGIN_REQUIRED); > > my $cgi = Bugzilla->cgi; >+ > my $dbh = Bugzilla->dbh; > my $template = Bugzilla->template; > my $vars = {}; >@@ -241,181 +242,194 @@ foreach my $bug (@bug_objects) { > } > } > >-# For security purposes, and because lots of other checks depend on it, >-# we set the product first before anything else. >-my $product_change; # Used only for strict_isolation checks, right now. >-if (should_set('product')) { >- foreach my $b (@bug_objects) { >- my $changed = $b->set_product(scalar $cgi->param('product'), >- { component => scalar $cgi->param('component'), >- version => scalar $cgi->param('version'), >- target_milestone => scalar $cgi->param('target_milestone'), >- change_confirmed => scalar $cgi->param('confirm_product_change'), >- other_bugs => \@bug_objects, >- }); >- $product_change ||= $changed; >- } >-} >- >-# strict_isolation checks mean that we should set the groups >-# immediately after changing the product. >-foreach my $b (@bug_objects) { >- foreach my $group (@{$b->product_obj->groups_valid}) { >- my $gid = $group->id; >- if (should_set("bit-$gid", 1)) { >- # Check ! first to avoid having to check defined below. >- if (!$cgi->param("bit-$gid")) { >- $b->remove_group($gid); >- } >- # "== 1" is important because mass-change uses -1 to mean >- # "don't change this restriction" >- elsif ($cgi->param("bit-$gid") == 1) { >- $b->add_group($gid); >- } >- } >- } >-} >+# Noura adds this >+foreach my $bug (@bug_objects) { > >-if ($cgi->param('id') && (defined $cgi->param('dependson') >- || defined $cgi->param('blocked')) ) >-{ >- $first_bug->set_dependencies(scalar $cgi->param('dependson'), >- scalar $cgi->param('blocked')); >-} >-# Right now, you can't modify dependencies on a mass change. >-else { >- $cgi->delete('dependson'); >- $cgi->delete('blocked'); >-} >+ my $args; > >-my $any_keyword_changes; >-if (defined $cgi->param('keywords')) { >- foreach my $b (@bug_objects) { >- my $return = >- $b->modify_keywords(scalar $cgi->param('keywords'), >- scalar $cgi->param('keywordaction')); >- $any_keyword_changes ||= $return; >+ if (should_set('product')) { >+ $args->{product} = scalar $cgi->param('product'); >+ $args->{component} = scalar $cgi->param('component'); >+ $args->{version} = scalar $cgi->param('version'); >+ $args->{target_milestone} = scalar $cgi->param('target_milestone'); >+ $args->{confirm_product_change} = scalar $cgi->param('confirm_product_change'); >+ $args->{other_bugs} = \@bug_objects; >+ } >+ >+ foreach my $group (@{$bug->product_obj->groups_valid}) { >+ my $gid = $group->id; >+ if (should_set("bit-$gid", 1)) { >+ # Check ! first to avoid having to check defined below. >+ if (!$cgi->param("bit-$gid")) { >+ push (@{$args->{remove_group}}, $gid); >+ } >+ # "== 1" is important because mass-change uses -1 to mean >+ # "don't change this restriction" >+ elsif ($cgi->param("bit-$gid") == 1) { >+ push (@{$args->{add_group}}, $gid); >+ } >+ } >+ } >+ >+ if ($cgi->param('id') && (defined $cgi->param('dependson') >+ || defined $cgi->param('blocked')) ) >+ { >+ $args->{dependson} = scalar $cgi->param('dependson'); >+ $args->{blocked} = scalar $cgi->param('blocked'); >+ } >+ # Right now, you can't modify dependencies on a mass change. >+ else { >+ $cgi->delete('dependson'); >+ $cgi->delete('blocked'); >+ } >+ if (defined $cgi->param('keywords')) { >+ my $keyword_arg_name = scalar $cgi->param('keywordaction') . "_keyword"; >+ $args->{$keyword_arg_name} = scalar $cgi->param('keywords'); > } >-} > >-# Component, target_milestone, and version are in here just in case >-# the 'product' field wasn't defined in the CGI. It doesn't hurt to set >-# them twice. >-my @set_fields = qw(op_sys rep_platform priority bug_severity >- component target_milestone version >- bug_file_loc status_whiteboard short_desc >- deadline remaining_time estimated_time); >-push(@set_fields, 'assigned_to') if !$cgi->param('set_default_assignee'); >-push(@set_fields, 'qa_contact') if !$cgi->param('set_default_qa_contact'); >-my @custom_fields = Bugzilla->active_custom_fields; >- >-my %methods = ( >- bug_severity => 'set_severity', >- rep_platform => 'set_platform', >- short_desc => 'set_summary', >- bug_file_loc => 'set_url', >-); >-foreach my $b (@bug_objects) { >+ my @custom_fields = Bugzilla->active_custom_fields; >+ > if (should_set('comment') || $cgi->param('work_time')) { >- # Add a comment as needed to each bug. This is done early because >- # there are lots of things that want to check if we added a comment. >- $b->add_comment(scalar($cgi->param('comment')), >- { isprivate => scalar $cgi->param('commentprivacy'), >- work_time => scalar $cgi->param('work_time') }); >- } >- foreach my $field_name (@set_fields) { >- if (should_set($field_name)) { >- my $method = $methods{$field_name}; >- $method ||= "set_" . $field_name; >- $b->$method($cgi->param($field_name)); >+ $args->{comment} = scalar $cgi->param('comment'); >+ $args->{work_time} = $cgi->param('work_time'); >+ $args->{commentprivacy} = scalar $cgi->param('commentprivacy'); >+ } >+ >+ # Component, target_milestone, and version are in here just in case >+ # the 'product' field wasn't defined in the CGI. It doesn't hurt to set >+ # them twice. >+ my @set_fields = qw(op_sys rep_platform priority bug_severity >+ component target_milestone version >+ bug_file_loc status_whiteboard short_desc >+ deadline remaining_time estimated_time); >+ >+ push(@set_fields, 'assigned_to') if !$cgi->param('set_default_assignee'); >+ push(@set_fields, 'qa_contact') if !$cgi->param('set_default_qa_contact'); >+ >+ my %field_mapping = ( >+ bug_severity => 'severity', >+ rep_platform => 'platform', >+ short_desc => 'summary', >+ bug_file_loc => 'url', >+ ); >+ >+ foreach my $field (@set_fields) { >+ if (should_set($field)) { >+ my $mapped_field = $field_mapping{$field}; >+ my $field_name = $mapped_field || $field; >+ $args->{$field_name} = $cgi->param($field); >+ >+ > } > } >- $b->reset_assigned_to if $cgi->param('set_default_assignee'); >- $b->reset_qa_contact if $cgi->param('set_default_qa_contact'); >+ >+ $args->{set_default_assignee} = $cgi->param('set_default_assignee'); >+ $args->{set_default_qa_contact} = $cgi->param('set_default_qa_contact'); > >- # And set custom fields. > foreach my $field (@custom_fields) { > my $fname = $field->name; > if (should_set($fname, 1)) { >- $b->set_custom_field($field, [$cgi->param($fname)]); >+ $args->{$fname} = $cgi->param($fname); > } > } >-} >+ >+ # Certain changes can only happen on individual bugs, never on mass-changes. >+ if (defined $cgi->param('id')) { >+ if (Bugzilla->params->{"usebugaliases"} && defined $cgi->param('alias')) { >+ $args->{alias} = $cgi->param('alias'); >+ } >+ >+ # reporter_accessible and cclist_accessible--these are only set if >+ # the user can change them and they appear on the page. >+ if (should_set('cclist_accessible', 1)) { >+ $args->{cclist_accessible} = $cgi->param('cclist_accessible'); >+ } >+ if (should_set('reporter_accessible', 1)) { >+ $args->{reporter_accessible} = $cgi->param('reporter_accessible'); >+ } >+ >+ # You can only mark/unmark comments as private on single bugs. If >+ # you're not in the insider group, this code won't do anything. >+ foreach my $cgi_field (grep(/^defined_isprivate/, $cgi->param())) { >+ $cgi_field =~ /(\d+)$/; >+ my $comment_id = $1; >+ if ($cgi->param("isprivate_$comment_id")){ >+ push (@{$args->{private_comment}}, $comment_id); >+ } >+ else { >+ push (@{$args->{non_private_comment}}, $comment_id); >+ } >+ } >+ } > >-# Certain changes can only happen on individual bugs, never on mass-changes. >-if (defined $cgi->param('id')) { >- # Since aliases are unique (like bug numbers), they can only be changed >- # for one bug at a time. >- if (Bugzilla->params->{"usebugaliases"} && defined $cgi->param('alias')) { >- $first_bug->set_alias($cgi->param('alias')); >- } >+ # We need to check the addresses involved in a CC change before we touch >+ # any bugs. What we'll do here is formulate the CC data into two arrays of >+ # users involved in this CC change. Then those arrays can be used later >+ # on for the actual change. >+ if (defined $cgi->param('newcc') >+ || defined $cgi->param('addselfcc') >+ || defined $cgi->param('removecc') >+ || defined $cgi->param('masscc')) { >+ >+ # If masscc is defined, then we came from buglist and need to either add or >+ # remove cc's... otherwise, we came from bugform and may need to do both. >+ my ($cc_add, $cc_remove) = ""; >+ if (defined $cgi->param('masscc')) { >+ if ($cgi->param('ccaction') eq 'add') { >+ $cc_add = join(' ',$cgi->param('masscc')); >+ } elsif ($cgi->param('ccaction') eq 'remove') { >+ $cc_remove = join(' ',$cgi->param('masscc')); >+ } >+ } else { >+ $cc_add = join(' ',$cgi->param('newcc')); >+ # We came from bug_form which uses a select box to determine what cc's >+ # need to be removed... >+ if (defined $cgi->param('removecc') && $cgi->param('cc')) { >+ $cc_remove = join (",", $cgi->param('cc')); >+ } >+ } > >- # reporter_accessible and cclist_accessible--these are only set if >- # the user can change them and they appear on the page. >- if (should_set('cclist_accessible', 1)) { >- $first_bug->set_cclist_accessible($cgi->param('cclist_accessible')) >- } >- if (should_set('reporter_accessible', 1)) { >- $first_bug->set_reporter_accessible($cgi->param('reporter_accessible')) >+ push(@{$args->{add_cc}}, split(/[\s,]+/, $cc_add)) if $cc_add; >+ push(@{$args->{add_cc}}, Bugzilla->user) if $cgi->param('addselfcc'); >+ >+ push(@{$args->{remove_cc}}, split(/[\s,]+/, $cc_remove)) if $cc_remove; > } >- >- # You can only mark/unmark comments as private on single bugs. If >- # you're not in the insider group, this code won't do anything. >- foreach my $field (grep(/^defined_isprivate/, $cgi->param())) { >- $field =~ /(\d+)$/; >- my $comment_id = $1; >- $first_bug->set_comment_is_private($comment_id, >- $cgi->param("isprivate_$comment_id")); >+ >+ # You cannot mark bugs as duplicates when changing several bugs at once >+ # (because currently there is no way to check for duplicate loops in that >+ # situation). >+ if (!$cgi->param('id') && $cgi->param('dup_id')) { >+ ThrowUserError('dupe_not_allowed'); > } >-} >- >-# We need to check the addresses involved in a CC change before we touch >-# any bugs. What we'll do here is formulate the CC data into two arrays of >-# users involved in this CC change. Then those arrays can be used later >-# on for the actual change. >-my (@cc_add, @cc_remove); >-if (defined $cgi->param('newcc') >- || defined $cgi->param('addselfcc') >- || defined $cgi->param('removecc') >- || defined $cgi->param('masscc')) { >- >- # If masscc is defined, then we came from buglist and need to either add or >- # remove cc's... otherwise, we came from bugform and may need to do both. >- my ($cc_add, $cc_remove) = ""; >- if (defined $cgi->param('masscc')) { >- if ($cgi->param('ccaction') eq 'add') { >- $cc_add = join(' ',$cgi->param('masscc')); >- } elsif ($cgi->param('ccaction') eq 'remove') { >- $cc_remove = join(' ',$cgi->param('masscc')); >- } >- } else { >- $cc_add = join(' ',$cgi->param('newcc')); >- # We came from bug_form which uses a select box to determine what cc's >- # need to be removed... >- if (defined $cgi->param('removecc') && $cgi->param('cc')) { >- $cc_remove = join (",", $cgi->param('cc')); >+ >+ # Set the status, resolution, and dupe_of (if needed). This has to be done >+ # down here, because the validity of status changes depends on other fields, >+ # such as Target Milestone. >+ >+ if (should_set('knob')) { >+ # First, get the correct resolution <select>, in case there is more >+ # than one open -> closed transition allowed. Allow to fallback to >+ # 'resolution' (useful when called from email_in.pl). >+ my $knob = $cgi->param('knob'); >+ my $status = new Bugzilla::Status({name => $knob}); >+ my $resolution; >+ if ($status) { >+ $resolution = $cgi->param('resolution_knob_' . $status->id) >+ || $cgi->param('resolution'); > } >+ else { >+ $resolution = $cgi->param('resolution_knob_change_resolution'); >+ } >+ $args->{knob} = $knob; >+ $args->{resolution} = $resolution; >+ $args->{dupe_id} = scalar $cgi->param('dup_id'); >+ > } >- >- push(@cc_add, split(/[\s,]+/, $cc_add)) if $cc_add; >- push(@cc_add, Bugzilla->user) if $cgi->param('addselfcc'); >- >- push(@cc_remove, split(/[\s,]+/, $cc_remove)) if $cc_remove; >-} >- >-foreach my $b (@bug_objects) { >- $b->remove_cc($_) foreach @cc_remove; >- $b->add_cc($_) foreach @cc_add; >- # Theoretically you could move a product without ever specifying >- # a new assignee or qa_contact, or adding/removing any CCs. So, >- # we have to check that the current assignee, qa, and CCs are still >- # valid if we've switched products, under strict_isolation. We can only >- # do that here. There ought to be some better way to do this, >- # architecturally, but I haven't come up with it. >- if ($product_change) { >- $b->_check_strict_isolation(); >- } >+ >+ $bug->set_all($args); > } >+ >+ > > my $move_action = $cgi->param('action') || ''; > if ($move_action eq Bugzilla->params->{'move-button-text'}) { >@@ -483,38 +497,6 @@ if ($move_action eq Bugzilla->params->{' > exit; > } > >- >-# You cannot mark bugs as duplicates when changing several bugs at once >-# (because currently there is no way to check for duplicate loops in that >-# situation). >-if (!$cgi->param('id') && $cgi->param('dup_id')) { >- ThrowUserError('dupe_not_allowed'); >-} >- >-# Set the status, resolution, and dupe_of (if needed). This has to be done >-# down here, because the validity of status changes depends on other fields, >-# such as Target Milestone. >-foreach my $b (@bug_objects) { >- if (should_set('knob')) { >- # First, get the correct resolution <select>, in case there is more >- # than one open -> closed transition allowed. Allow to fallback to >- # 'resolution' (useful when called from email_in.pl). >- my $knob = $cgi->param('knob'); >- my $status = new Bugzilla::Status({name => $knob}); >- my $resolution; >- if ($status) { >- $resolution = $cgi->param('resolution_knob_' . $status->id) >- || $cgi->param('resolution'); >- } >- else { >- $resolution = $cgi->param('resolution_knob_change_resolution'); >- } >- >- # Translate the knob values into new status and resolution values. >- $b->process_knob($knob, $resolution, scalar $cgi->param('dup_id')); >- } >-} >- > ############################## > # Do Actual Database Updates # > ############################## >Index: template/en/default/global/user-error.html.tmpl >=================================================================== >RCS file: /cvs/qa/rh_bugzilla_3/template/en/default/global/user-error.html.tmpl,v >retrieving revision 1.19 >diff -p -u -r1.19 user-error.html.tmpl >--- template/en/default/global/user-error.html.tmpl 11 Mar 2008 03:47:17 -0000 1.19 >+++ template/en/default/global/user-error.html.tmpl 11 Mar 2008 06:01:45 -0000 >@@ -344,6 +344,17 @@ > The custom field '[% name FILTER html %]' cannot be deleted because > at least one [% terms.bug %] has a non empty value for this field. > >+ [% ELSIF error == "product_update_not_allowed" %] >+ [% title = "Product Update Not Allowed" %] >+ Missing required information to change a product of a [% terms.bug %]. >+ You must specify all the following: >+ component name, version, and target milestone. >+ >+ [% ELSIF error == "alias_not_allowed" %] >+ [% title = "Alias Update Not Allowed" %] >+ You cannot update the alias when changing several >+ [% terms.bug %] at once. >+ > [% ELSIF error == "dependency_loop_multi" %] > [% title = "Dependency Loop Detected" %] > The following [% terms.bug %](s) would appear on both the "depends on" >@@ -358,6 +369,11 @@ > [% title = "Dependency Loop Detected" %] > You can't make [% terms.abug %] block itself or depend on itself. > >+ [% ELSIF error == "dependencies_not_allowed" %] >+ [% title = "Cannot mark $terms.Bug as dependson/blocked" %] >+ You cannot mark [% terms.abug %] as dependson or blocked when >+ changing several [% terms.bugs %] at once. >+ > [% ELSIF error == "dupe_id_required" %] > [% title = "Duplicate $terms.Bug Id Required" %] > You must specify [% terms.abug %] id to mark this [% terms.bug %]
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 433744
:
295483
|
296081
|
296620
|
296768
|
297132
|
297564
|
297565