From 861dd56bc901477eec23e060a143e24cc8b79384 Mon Sep 17 00:00:00 2001 From: Dave Lawrence Date: Thu, 11 Apr 2013 15:11:32 +0800 Subject: Bug 859480: Ability to ignore specific bugs (not get email from them, even as the reporter) --- Bugzilla/Bug.pm | 41 +++++++++++++++++++++++++++++++---------- Bugzilla/BugMail.pm | 11 ++++++++--- Bugzilla/Flag.pm | 3 +++ Bugzilla/User.pm | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 13 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index 45381e6e1..a873d63be 100644 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -786,8 +786,9 @@ sub run_create_validators { sub update { my $self = shift; + my $dbh = Bugzilla->dbh; + my $user = Bugzilla->user; - my $dbh = Bugzilla->dbh; # XXX This is just a temporary hack until all updating happens # inside this function. my $delta_ts = shift || $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); @@ -878,7 +879,7 @@ sub update { # Add an activity entry for the other bug. LogActivityEntry($removed_id, $other, $self->id, '', - Bugzilla->user->id, $delta_ts); + $user->id, $delta_ts); # Update delta_ts on the other bug so that we trigger mid-airs. $dbh->do('UPDATE bugs SET delta_ts = ? WHERE bug_id = ?', undef, $delta_ts, $removed_id); @@ -889,7 +890,7 @@ sub update { # Add an activity entry for the other bug. LogActivityEntry($added_id, $other, '', $self->id, - Bugzilla->user->id, $delta_ts); + $user->id, $delta_ts); # Update delta_ts on the other bug so that we trigger mid-airs. $dbh->do('UPDATE bugs SET delta_ts = ? WHERE bug_id = ?', undef, $delta_ts, $added_id); @@ -937,7 +938,7 @@ sub update { $comment = Bugzilla::Comment->insert_create_data($comment); if ($comment->work_time) { LogActivityEntry($self->id, "work_time", "", $comment->work_time, - Bugzilla->user->id, $delta_ts); + $user->id, $delta_ts); } } @@ -948,7 +949,7 @@ sub update { my ($from, $to) = $comment->is_private ? (0, 1) : (1, 0); LogActivityEntry($self->id, "longdescs.isprivate", $from, $to, - Bugzilla->user->id, $delta_ts, $comment->id); + $user->id, $delta_ts, $comment->id); } # Insert the values into the multiselect value tables @@ -993,8 +994,8 @@ sub update { my $change = $changes->{$field}; my $from = defined $change->[0] ? $change->[0] : ''; my $to = defined $change->[1] ? $change->[1] : ''; - LogActivityEntry($self->id, $field, $from, $to, Bugzilla->user->id, - $delta_ts); + LogActivityEntry($self->id, $field, $from, $to, + $user->id, $delta_ts); } # Check if we have to update the duplicates table and the other bug. @@ -1008,7 +1009,7 @@ sub update { $update_dup->update(); } } - + $changes->{'dup_id'} = [$old_dup || undef, $cur_dup || undef]; } @@ -1025,6 +1026,25 @@ sub update { $self->{delta_ts} = $delta_ts; } + # Update bug ignore data if user wants to ignore mail for this bug + if (exists $self->{'bug_ignored'}) { + my $bug_ignored_changed; + if ($self->{'bug_ignored'} && !$user->is_bug_ignored($self->id)) { + $dbh->do('INSERT INTO email_bug_ignore + (user_id, bug_id) VALUES (?, ?)', + undef, $user->id, $self->id); + $bug_ignored_changed = 1; + + } + elsif (!$self->{'bug_ignored'} && $user->is_bug_ignored($self->id)) { + $dbh->do('DELETE FROM email_bug_ignore + WHERE user_id = ? AND bug_id = ?', + undef, $user->id, $self->id); + $bug_ignored_changed = 1; + } + delete $user->{bugs_ignored} if $bug_ignored_changed; + } + $dbh->bz_commit_transaction(); # The only problem with this here is that update() is often called @@ -1042,7 +1062,7 @@ sub update { # Also flush the visible_bugs cache for this bug as the user's # relationship with this bug may have changed. - delete Bugzilla->user->{_visible_bugs_cache}->{$self->id}; + delete $user->{_visible_bugs_cache}->{$self->id}; return $changes; } @@ -2313,7 +2333,7 @@ sub set_all { # 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, because if they *did* change the assignee, qa, or CC, - # then we don't want to check the original ones, only the new ones. + # then we don't want to check the original ones, only the new ones. $self->_check_strict_isolation() if $product_changed; } @@ -2343,6 +2363,7 @@ sub reset_assigned_to { my $comp = $self->component_obj; $self->set_assigned_to($comp->default_assignee); } +sub set_bug_ignored { $_[0]->set('bug_ignored', $_[1]); } sub set_cclist_accessible { $_[0]->set('cclist_accessible', $_[1]); } sub set_comment_is_private { my ($self, $comment_id, $isprivate) = @_; diff --git a/Bugzilla/BugMail.pm b/Bugzilla/BugMail.pm index fe611d55d..37421ce3e 100644 --- a/Bugzilla/BugMail.pm +++ b/Bugzilla/BugMail.pm @@ -263,6 +263,13 @@ sub Send { # Deleted users must be excluded. next unless $user; + # If email notifications are disabled for this account, or the bug + # is ignored, there is no need to do additional checks. + if ($user->email_disabled || $user->is_bug_ignored($id)) { + push(@excluded, $user->login); + next; + } + if ($user->can_see_bug($id)) { # Go through each role the user has and see if they want mail in # that role. @@ -279,7 +286,7 @@ sub Send { } } } - + if (scalar(%rels_which_want)) { # So the user exists, can see the bug, and wants mail in at least # one role. But do we want to send it to them? @@ -301,8 +308,6 @@ sub Send { ($user->login eq 'sync-1@bugzilla.tld' || $user->login !~ /\.tld$/)) { - # OK, OK, if we must. Email the user. - # Don't show summaries for bugs the user can't access, and # provide a hook for extensions such as SecureMail to filter # this list. diff --git a/Bugzilla/Flag.pm b/Bugzilla/Flag.pm index 5f4f90b6c..d3e9b1d37 100644 --- a/Bugzilla/Flag.pm +++ b/Bugzilla/Flag.pm @@ -1021,6 +1021,9 @@ sub notify { } foreach my $to (keys %recipients) { + # Skip sending if user is ignoring the bug. + next if ($recipients{$to} && $recipients{$to}->is_bug_ignored($bug->id)); + # Add threadingmarker to allow flag notification emails to be the # threaded similar to normal bug change emails. my $thread_user_id = $recipients{$to} ? $recipients{$to}->id : 0; diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm index 151919bf8..2c11c2381 100644 --- a/Bugzilla/User.pm +++ b/Bugzilla/User.pm @@ -432,6 +432,31 @@ sub tags { return $self->{tags}; } +sub bugs_ignored { + my ($self) = @_; + my $dbh = Bugzilla->dbh; + if (!defined $self->{'bugs_ignored'}) { + $self->{'bugs_ignored'} = $dbh->selectall_arrayref( + 'SELECT bugs.bug_id AS id, + bugs.bug_status AS status, + bugs.short_desc AS summary + FROM bugs + INNER JOIN email_bug_ignore + ON bugs.bug_id = email_bug_ignore.bug_id + WHERE user_id = ?', + { Slice => {} }, $self->id); + # Go ahead and load these into the visible bugs cache + # to speed up can_see_bug checks later + $self->visible_bugs([ map { $_->{'id'} } @{ $self->{'bugs_ignored'} } ]); + } + return $self->{'bugs_ignored'}; +} + +sub is_bug_ignored { + my ($self, $bug_id) = @_; + return (grep {$_->{'id'} == $bug_id} @{$self->bugs_ignored}) ? 1 : 0; +} + ########################## # Saved Recent Bug Lists # ########################## @@ -2211,6 +2236,34 @@ groups. Returns a hashref with tag IDs as key, and a hashref with tag 'id', 'name' and 'bug_count' as value. +=item C + +Returns an array of hashrefs containing information about bugs currently +being ignored by the user. + +Each hashref contains the following information: + +=over + +=item C + +C The id of the bug. + +=item C + +C The current status of the bug. + +=item C + +C The current summary of the bug. + +=back + +=item C + +Returns true if the user does not want email notifications for the +specified bug ID, else returns false. + =back =head2 Saved Recent Bug Lists -- cgit v1.2.3-24-g4f1b