From a88fc0757d5bd8e70cad0572ab4d29a8817beb84 Mon Sep 17 00:00:00 2001 From: "lpsolit%gmail.com" <> Date: Fri, 5 Jan 2007 01:48:16 +0000 Subject: Bug 364216: Flag::retarget() is broken (again) - Patch by Frédéric Buclin r/a=myk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bugzilla/Flag.pm | 57 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 22 deletions(-) (limited to 'Bugzilla/Flag.pm') diff --git a/Bugzilla/Flag.pm b/Bugzilla/Flag.pm index f0acc3d2e..9e7483838 100644 --- a/Bugzilla/Flag.pm +++ b/Bugzilla/Flag.pm @@ -139,6 +139,11 @@ Returns the user who set the flag, as a Bugzilla::User object. Returns the user who has been requested to set the flag, as a Bugzilla::User object. +=item C + +Returns the attachment object the flag belongs to if the flag +is an attachment flag, else undefined. + =back =cut @@ -166,6 +171,15 @@ sub requestee { return $self->{'requestee'}; } +sub attachment { + my $self = shift; + return undef unless $self->attach_id; + + require Bugzilla::Attachment; + $self->{'attachment'} ||= Bugzilla::Attachment->get($self->attach_id); + return $self->{'attachment'}; +} + ################################ ## Searching/Retrieving Flags ## ################################ @@ -519,9 +533,10 @@ sub process { AND i.type_id IS NULL", undef, $bug_id); - foreach my $flag_id (@$flag_ids) { - my $is_retargetted = retarget($flag_id, $bug, $attachment); - clear($flag_id, $bug, $attachment) unless $is_retargetted; + my $flags = Bugzilla::Flag->new_from_list($flag_ids); + foreach my $flag (@$flags) { + my $is_retargetted = retarget($flag, $bug); + clear($flag, $bug, $flag->attachment) unless $is_retargetted; } $flag_ids = $dbh->selectcol_arrayref( @@ -534,9 +549,10 @@ sub process { AND (bugs.component_id = e.component_id OR e.component_id IS NULL)", undef, $bug_id); - foreach my $flag_id (@$flag_ids) { - my $is_retargetted = retarget($flag_id, $bug, $attachment); - clear($flag_id, $bug, $attachment) unless $is_retargetted; + $flags = Bugzilla::Flag->new_from_list($flag_ids); + foreach my $flag (@$flags) { + my $is_retargetted = retarget($flag, $bug); + clear($flag, $bug, $flag->attachment) unless $is_retargetted; } # Take a snapshot of flags after changes. @@ -751,7 +767,7 @@ sub modify { notify($flag, $bug, $attachment); } elsif ($status eq 'X') { - clear($flag->id, $bug, $attachment); + clear($flag, $bug, $attachment); } push(@flags, $flag); @@ -764,11 +780,11 @@ sub modify { =over -=item C +=item C Change the type of the flag, if possible. The new flag type must have the same name as the current flag type, must exist in the product and -attachment the bug is in, and the current settings of the flag must pass +component the bug is in, and the current settings of the flag must pass validation. If no such flag type can be found, the type remains unchanged. Retargetting flags is a good way to keep flags when moving bugs from one @@ -782,16 +798,15 @@ the same meaning, but with different settings. =cut sub retarget { - my ($flag_id, $bug, $attachment) = @_; + my ($flag, $bug) = @_; my $dbh = Bugzilla->dbh; - my $flag = new Bugzilla::Flag($flag_id); # We are looking for flagtypes having the same name as the flagtype # to which the current flag belongs, and being in the new product and # component of the bug. my $flagtypes = Bugzilla::FlagType::match( {'name' => $flag->name, - 'target_type' => $attachment ? 'attachment' : 'bug', + 'target_type' => $flag->type->target_type, 'is_active' => 1, 'product_id' => $bug->product_id, 'component_id' => $bug->component_id}); @@ -803,17 +818,15 @@ sub retarget { # assuming the setter/requester is allowed to set/request flags # belonging to this flagtype. my $requestee = $flag->requestee ? [$flag->requestee->login] : []; - my $attach_id = $attachment ? $attachment->id : undef; - my $is_private = $attachment ? $attachment->isprivate : 0; + my $is_private = ($flag->attachment) ? $flag->attachment->isprivate : 0; my $is_retargetted = 0; foreach my $flagtype (@$flagtypes) { # Get the number of flags of this type already set for this target. my $has_flags = count( { 'type_id' => $flagtype->id, - 'target_type' => $attachment ? 'attachment' : 'bug', 'bug_id' => $bug->bug_id, - 'attach_id' => $attach_id }); + 'attach_id' => $flag->attach_id }); # Do not create a new flag of this type if this flag type is # not multiplicable and already has a flag set. @@ -824,7 +837,7 @@ sub retarget { Bugzilla->error_mode(ERROR_MODE_DIE); eval { _validate(undef, $flagtype, $flag->status, $flag->setter, - $requestee, $is_private, $bug->bug_id, $attach_id); + $requestee, $is_private, $bug->bug_id, $flag->attach_id); }; Bugzilla->error_mode($error_mode_cache); # If the validation failed, then we cannot use this flagtype. @@ -844,7 +857,7 @@ sub retarget { =over -=item C +=item C Remove a flag from the DB. @@ -853,11 +866,10 @@ Remove a flag from the DB. =cut sub clear { - my ($id, $bug, $attachment) = @_; + my ($flag, $bug, $attachment) = @_; my $dbh = Bugzilla->dbh; - my $flag = new Bugzilla::Flag($id); - $dbh->do('DELETE FROM flags WHERE id = ?', undef, $id); + $dbh->do('DELETE FROM flags WHERE id = ?', undef, $flag->id); # If we cancel a pending request, we have to notify the requester # (if he wants to). @@ -1042,7 +1054,8 @@ sub CancelRequests { # Take a snapshot of flags before any changes. my @old_summaries = snapshot($bug->bug_id, $attachment->id) if ($timestamp); - foreach my $flag (@$request_ids) { clear($flag, $bug, $attachment) } + my $flags = Bugzilla::Flag->new_from_list($request_ids); + foreach my $flag (@$flags) { clear($flag, $bug, $attachment) } # If $timestamp is undefined, do not update the activity table return unless ($timestamp); -- cgit v1.2.3-24-g4f1b