Bug 364216: Flag::retarget() is broken (again) - Patch by Fr��d��ric Buclin <LpSolit@gmail.com> r/a=myk

This commit is contained in:
lpsolit%gmail.com 2007-01-04 17:48:17 +00:00
Родитель 23a0f6cb6d
Коммит 837541ed1c
2 изменённых файлов: 43 добавлений и 33 удалений

Просмотреть файл

@ -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 Returns the user who has been requested to set the flag, as a
Bugzilla::User object. Bugzilla::User object.
=item C<attachment>
Returns the attachment object the flag belongs to if the flag
is an attachment flag, else undefined.
=back =back
=cut =cut
@ -166,6 +171,15 @@ sub requestee {
return $self->{'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 ## ## Searching/Retrieving Flags ##
################################ ################################
@ -519,9 +533,10 @@ sub process {
AND i.type_id IS NULL", AND i.type_id IS NULL",
undef, $bug_id); undef, $bug_id);
foreach my $flag_id (@$flag_ids) { my $flags = Bugzilla::Flag->new_from_list($flag_ids);
my $is_retargetted = retarget($flag_id, $bug, $attachment); foreach my $flag (@$flags) {
clear($flag_id, $bug, $attachment) unless $is_retargetted; my $is_retargetted = retarget($flag, $bug);
clear($flag, $bug, $flag->attachment) unless $is_retargetted;
} }
$flag_ids = $dbh->selectcol_arrayref( $flag_ids = $dbh->selectcol_arrayref(
@ -534,9 +549,10 @@ sub process {
AND (bugs.component_id = e.component_id OR e.component_id IS NULL)", AND (bugs.component_id = e.component_id OR e.component_id IS NULL)",
undef, $bug_id); undef, $bug_id);
foreach my $flag_id (@$flag_ids) { $flags = Bugzilla::Flag->new_from_list($flag_ids);
my $is_retargetted = retarget($flag_id, $bug, $attachment); foreach my $flag (@$flags) {
clear($flag_id, $bug, $attachment) unless $is_retargetted; my $is_retargetted = retarget($flag, $bug);
clear($flag, $bug, $flag->attachment) unless $is_retargetted;
} }
# Take a snapshot of flags after changes. # Take a snapshot of flags after changes.
@ -751,7 +767,7 @@ sub modify {
notify($flag, $bug, $attachment); notify($flag, $bug, $attachment);
} }
elsif ($status eq 'X') { elsif ($status eq 'X') {
clear($flag->id, $bug, $attachment); clear($flag, $bug, $attachment);
} }
push(@flags, $flag); push(@flags, $flag);
@ -764,11 +780,11 @@ sub modify {
=over =over
=item C<retarget($flag_id, $bug, $attachment)> =item C<retarget($flag, $bug)>
Change the type of the flag, if possible. The new flag type must have 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 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. 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 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 =cut
sub retarget { sub retarget {
my ($flag_id, $bug, $attachment) = @_; my ($flag, $bug) = @_;
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
my $flag = new Bugzilla::Flag($flag_id);
# We are looking for flagtypes having the same name as the flagtype # 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 # to which the current flag belongs, and being in the new product and
# component of the bug. # component of the bug.
my $flagtypes = Bugzilla::FlagType::match( my $flagtypes = Bugzilla::FlagType::match(
{'name' => $flag->name, {'name' => $flag->name,
'target_type' => $attachment ? 'attachment' : 'bug', 'target_type' => $flag->type->target_type,
'is_active' => 1, 'is_active' => 1,
'product_id' => $bug->product_id, 'product_id' => $bug->product_id,
'component_id' => $bug->component_id}); 'component_id' => $bug->component_id});
@ -803,17 +818,15 @@ sub retarget {
# assuming the setter/requester is allowed to set/request flags # assuming the setter/requester is allowed to set/request flags
# belonging to this flagtype. # belonging to this flagtype.
my $requestee = $flag->requestee ? [$flag->requestee->login] : []; my $requestee = $flag->requestee ? [$flag->requestee->login] : [];
my $attach_id = $attachment ? $attachment->id : undef; my $is_private = ($flag->attachment) ? $flag->attachment->isprivate : 0;
my $is_private = $attachment ? $attachment->isprivate : 0;
my $is_retargetted = 0; my $is_retargetted = 0;
foreach my $flagtype (@$flagtypes) { foreach my $flagtype (@$flagtypes) {
# Get the number of flags of this type already set for this target. # Get the number of flags of this type already set for this target.
my $has_flags = count( my $has_flags = count(
{ 'type_id' => $flagtype->id, { 'type_id' => $flagtype->id,
'target_type' => $attachment ? 'attachment' : 'bug',
'bug_id' => $bug->bug_id, '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 # Do not create a new flag of this type if this flag type is
# not multiplicable and already has a flag set. # not multiplicable and already has a flag set.
@ -824,7 +837,7 @@ sub retarget {
Bugzilla->error_mode(ERROR_MODE_DIE); Bugzilla->error_mode(ERROR_MODE_DIE);
eval { eval {
_validate(undef, $flagtype, $flag->status, $flag->setter, _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); Bugzilla->error_mode($error_mode_cache);
# If the validation failed, then we cannot use this flagtype. # If the validation failed, then we cannot use this flagtype.
@ -844,7 +857,7 @@ sub retarget {
=over =over
=item C<clear($id, $bug, $attachment)> =item C<clear($flag, $bug, $attachment)>
Remove a flag from the DB. Remove a flag from the DB.
@ -853,11 +866,10 @@ Remove a flag from the DB.
=cut =cut
sub clear { sub clear {
my ($id, $bug, $attachment) = @_; my ($flag, $bug, $attachment) = @_;
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
my $flag = new Bugzilla::Flag($id); $dbh->do('DELETE FROM flags WHERE id = ?', undef, $flag->id);
$dbh->do('DELETE FROM flags WHERE id = ?', undef, $id);
# If we cancel a pending request, we have to notify the requester # If we cancel a pending request, we have to notify the requester
# (if he wants to). # (if he wants to).
@ -1042,7 +1054,8 @@ sub CancelRequests {
# Take a snapshot of flags before any changes. # Take a snapshot of flags before any changes.
my @old_summaries = snapshot($bug->bug_id, $attachment->id) if ($timestamp); 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 # If $timestamp is undefined, do not update the activity table
return unless ($timestamp); return unless ($timestamp);

Просмотреть файл

@ -387,8 +387,7 @@ sub update {
# Clear existing flags for bugs/attachments in categories no longer on # Clear existing flags for bugs/attachments in categories no longer on
# the list of inclusions or that have been added to the list of exclusions. # the list of inclusions or that have been added to the list of exclusions.
my $flags = $dbh->selectall_arrayref('SELECT DISTINCT flags.id, flags.bug_id, my $flag_ids = $dbh->selectcol_arrayref('SELECT DISTINCT flags.id
flags.attach_id
FROM flags FROM flags
INNER JOIN bugs INNER JOIN bugs
ON flags.bug_id = bugs.bug_id ON flags.bug_id = bugs.bug_id
@ -401,14 +400,13 @@ sub update {
WHERE flags.type_id = ? WHERE flags.type_id = ?
AND i.type_id IS NULL', AND i.type_id IS NULL',
undef, $id); undef, $id);
my $flags = Bugzilla::Flag->new_from_list($flag_ids);
foreach my $flag (@$flags) { foreach my $flag (@$flags) {
my ($flag_id, $bug_id, $attach_id) = @$flag; my $bug = new Bugzilla::Bug($flag->bug_id);
my $bug = new Bugzilla::Bug($bug_id); Bugzilla::Flag::clear($flag, $bug, $flag->attachment);
my $attachment = $attach_id ? Bugzilla::Attachment->get($attach_id) : undef;
Bugzilla::Flag::clear($flag_id, $bug, $attachment);
} }
$flags = $dbh->selectall_arrayref('SELECT DISTINCT flags.id, flags.bug_id, flags.attach_id $flag_ids = $dbh->selectcol_arrayref('SELECT DISTINCT flags.id
FROM flags FROM flags
INNER JOIN bugs INNER JOIN bugs
ON flags.bug_id = bugs.bug_id ON flags.bug_id = bugs.bug_id
@ -420,11 +418,10 @@ sub update {
AND (bugs.component_id = e.component_id AND (bugs.component_id = e.component_id
OR e.component_id IS NULL)', OR e.component_id IS NULL)',
undef, $id); undef, $id);
$flags = Bugzilla::Flag->new_from_list($flag_ids);
foreach my $flag (@$flags) { foreach my $flag (@$flags) {
my ($flag_id, $bug_id, $attach_id) = @$flag; my $bug = new Bugzilla::Bug($flag->bug_id);
my $bug = new Bugzilla::Bug($bug_id); Bugzilla::Flag::clear($flag, $bug, $flag->attachment);
my $attachment = $attach_id ? Bugzilla::Attachment->get($attach_id) : undef;
Bugzilla::Flag::clear($flag_id, $bug, $attachment);
} }
# Now silently remove requestees from flags which are no longer # Now silently remove requestees from flags which are no longer