Commit 8f025114 authored by myk%mozilla.org's avatar myk%mozilla.org

Fix for bug 122900: implements email preference for unconfirmed bugs.

r=jouni
parent 3713224a
...@@ -38,6 +38,7 @@ use RelationSet; ...@@ -38,6 +38,7 @@ use RelationSet;
sub processmail_sillyness { sub processmail_sillyness {
my $zz; my $zz;
$zz = $::db; $zz = $::db;
$zz = $::unconfirmedstate;
} }
$| = 1; $| = 1;
...@@ -232,7 +233,10 @@ sub ProcessOneBug { ...@@ -232,7 +233,10 @@ sub ProcessOneBug {
# #
my $count = 0; my $count = 0;
my @currentEmailAttributes = getEmailAttributes($newcomments, @diffs); # Get a list of the reasons a user might receive email about the bug.
my @currentEmailAttributes =
getEmailAttributes(\%values, \@diffs, $newcomments);
my (@assigned_toList,@reporterList,@qa_contactList,@ccList) = (); my (@assigned_toList,@reporterList,@qa_contactList,@ccList) = ();
#open(LOG, ">>/tmp/maillog"); #open(LOG, ">>/tmp/maillog");
...@@ -401,12 +405,17 @@ sub filterExcludeList ($$) { ...@@ -401,12 +405,17 @@ sub filterExcludeList ($$) {
# if no flags are set and there was some other field change # if no flags are set and there was some other field change
# set the Status flag # set the Status flag
# #
sub getEmailAttributes ($@) { sub getEmailAttributes (\%\@$) {
my ($commentField,@fieldDiffs) = @_; my ($bug, $fieldDiffs, $commentField) = @_;
my (@flags,@uniqueFlags,%alreadySeen) = (); my (@flags,@uniqueFlags,%alreadySeen) = ();
foreach my $ref (@fieldDiffs) { # Add a flag if the status of the bug is "unconfirmed".
if ($bug->{'bug_status'} eq $::unconfirmedstate) {
push (@flags, 'Unconfirmed')
};
foreach my $ref (@$fieldDiffs) {
my ($who, $fieldName, $when, $old, $new) = (@$ref); my ($who, $fieldName, $when, $old, $new) = (@$ref);
#print qq{field: $fieldName $new<br>}; #print qq{field: $fieldName $new<br>};
...@@ -448,7 +457,7 @@ sub getEmailAttributes ($@) { ...@@ -448,7 +457,7 @@ sub getEmailAttributes ($@) {
} }
# default fallthrough for any unflagged change is 'Other' # default fallthrough for any unflagged change is 'Other'
if ( @flags == 0 && @fieldDiffs != 0 ) { if ( @flags == 0 && @$fieldDiffs != 0 ) {
push (@flags, 'Other'); push (@flags, 'Other');
} }
...@@ -470,168 +479,131 @@ sub getEmailAttributes ($@) { ...@@ -470,168 +479,131 @@ sub getEmailAttributes ($@) {
} }
sub filterEmailGroup ($$$) { sub filterEmailGroup ($$$) {
# This function figures out who should receive email about the bug
my ($emailGroup,$refAttributes,$emailList) = @_; # based on the user's role with regard to the bug (assignee, reporter
my @emailAttributes = @$refAttributes; # etc.), the changes that occurred (new comments, attachment added,
my @emailList = split(/,/,$emailList); # status changed etc.) and the user's email preferences.
my @filteredList = ();
# Returns a filtered list of those users who would receive email
# about these changes, and adds the names of those users who would
# the force list for this email group needs to be checked as well # not receive email about them to the global @excludedAddresses list.
#
push @emailList, @{$force{$emailGroup}}; my ($role, $reasons, $users) = @_;
# Check this user for any watchers... doing this here allows them to inhert the # Make a list of users to filter.
# relationship to the bug of the person they are watching (if the person they my @users = split( /,/ , $users );
# are watching is an owner, their mail is filtered as if they were the owner).
if (Param("supportwatchers")) { # Treat users who are in the process of being removed from this role
my @watchers; # as if they were still in it.
foreach my $person(@emailList) { push @users, @{$force{$role}};
my $personId = DBname_to_id($person);
SendSQL("SELECT watcher FROM watch WHERE watched = $personId"); # If this installation supports user watching, add to the list those
while(MoreSQLData()) { # users who are watching other users already on the list. By doing
my ($watcher) = FetchSQLData(); # this here, we allow watchers to inherit the roles of the people
if ($watcher) { # they are watching while at the same time filtering email for watchers
push (@watchers, DBID_to_name($watcher)); # based on their own preferences.
} if (Param("supportwatchers") && scalar(@users)) {
} # Convert the unfiltered list of users into an SQL-quoted,
} # comma-separated string suitable for use in an SQL query.
push(@emailList, @watchers); my $watched = join(",", map(SqlQuote($_), @users));
} SendSQL("SELECT watchers.login_name
FROM watch, profiles AS watchers, profiles AS watched
WHERE watched.login_name IN ($watched)
foreach my $person (@emailList) { AND watched.userid = watch.watched
AND watch.watcher = watchers.userid");
my $lastCount = @filteredList; push (@users, FetchOneColumn()) while MoreSQLData();
}
if ( $person eq '' ) { next; }
# Initialize the list of recipients.
my $userid = DBname_to_id($person); my @recipients = ();
if ( ! $userid ) { USER: foreach my $user (@users) {
push(@filteredList,$person); next unless $user;
# Get the user's unique ID, and if the user is not registered
# (no idea why unregistered users should even be on this list,
# but the code that was here before I re-wrote it allows this),
# then we do not have any preferences for them, so assume the
# default preference to receive all mail for any reason.
my $userid = DBname_to_id($user);
if (!$userid) {
push(@recipients, $user);
next; next;
} }
SendSQL("SELECT emailflags FROM profiles WHERE " . # Get the user's email preferences from the database.
"userid = $userid" ); SendSQL("SELECT emailflags FROM profiles WHERE userid = $userid");
my $prefs = FetchOneColumn();
my ($userFlagString) = FetchSQLData();
# If the sender doesn't want email, exclude them from list
if (lc($person) eq $nametoexclude) {
if ( defined ($userFlagString) &&
$userFlagString =~ /ExcludeSelf\~on/ ) {
push (@excludedAddresses,$person); # If the user's preferences are empty, assume the default preference
# to receive all mail. This happens when the installation upgraded
# from a version of Bugzilla without email preferences to one with
# them, but the user has not set their preferences yet.
if (!defined($prefs) || $prefs !~ /email/) {
push(@recipients, $user);
next; next;
} }
}
# if the users database entry is empty, send them all email
# by default (they have not accessed userprefs.cgi recently).
if ( !defined($userFlagString) || !($userFlagString =~ /email/) ) {
push(@filteredList,$person);
}
else {
# the 255 param is here, because without a third param,
# split will trim any trailing null fields, which causes perl
# to eject lots of warnings. any suitably large number would
# do.
my %userFlags = split(/~/, $userFlagString, 255);
# The default condition is to send each person email.
# If we match the email attribute with the user flag, and
# they do not want email, then remove them from the list.
push(@filteredList,$person); # Write the user's preferences into a Perl record indexed by
# preference name. We pass the value "255" to the split function
# because otherwise split will trim trailing null fields, causing
# Perl to generate lots of warnings. Any suitably large number
# would do.
my %prefs = split(/~/, $prefs, 255);
my $detectedOn = 0; # If this user is the one who made the change in the first place,
# and they prefer not to receive mail about their own changes,
foreach my $attribute (@emailAttributes) { # filter them from the list.
if (lc($user) eq $nametoexclude && $prefs{'ExcludeSelf'} eq 'on') {
my $matchName = 'email' . $emailGroup . $attribute; push(@excludedAddresses, $user);
# **** Kludge... quick and dirty fix for 2.12
# http://bugzilla.mozilla.org/show_bug.cgi?id=73665
# If this pref is new (it's been added since this user
# last updated their filtering prefs, $userFlags{$matchName}
# will be undefined. This should be considered a match
# so that new prefs will default to 'on'
if (!defined($userFlags{$matchName})) {
$detectedOn = 1;
}
while ((my $flagName, my $flagValue) = each %userFlags) {
if ($flagName !~ /$emailGroup/) {
next; next;
} }
if ($flagName eq $matchName){ # If the user doesn't want to receive email about unconfirmed
if ($flagValue eq 'on') { # bugs, that setting overrides their other preferences, including
$detectedOn = 1; # the preference to receive email when they are added to or removed
} # from a role, so remove them from the list before checking their
# other preferences.
if (grep(/Unconfirmed/, @$reasons)
&& exists($prefs{"email${role}Unconfirmed"})
&& $prefs{"email${role}Unconfirmed"} eq '')
{
push(@excludedAddresses, $user);
next;
} }
} # for each userFlag # If the user was added to or removed from this role, and they
# prefer to receive email when that happens, send them mail.
} # for each email attribute # Note: This was originally written to send email when users
# were removed from roles and was later enhanced for additions,
# if the current flag hasn't been detected on at least once, # but for simplicity's sake the name "Removeme" was retained.
# this person gets filtered from this group. if (grep($_ eq $user, @{$force{$role}})
# && $prefs{"email${role}Removeme"} eq 'on')
if (! $detectedOn) { {
pop(@filteredList); push (@recipients, $user);
next;
} }
# check to see if the person was added to or removed from # If the user prefers to be included in mail about this change,
# this email group. # or they haven't specified a preference for it (because they
# Note: This was originally written as only removed from # haven't visited the email preferences page since the preference
# and was rewritten to be Added/Removed, but for simplicity # was added, in which case we include them by default), add them
# sake, the name "Removeme" wasn't changed. # to the list of recipients.
# http://bugzilla.mozilla.org/show_bug.cgi?id=71912 foreach my $reason (@$reasons) {
my $pref = "email$role$reason";
if ( grep ($_ eq $person, @{$force{$emailGroup}} ) ) { if (!exists($prefs{$pref}) || $prefs{$pref} eq 'on') {
push(@recipients, $user);
# if so, see if they want mail about that next USER;
#
if ( $userFlags{'email' . $emailGroup . 'Removeme'} eq 'on' ) {
# we definitely want mail sent to this person, since
# inclusion on a mail takes precedence over the previous
# exclusion
# have they been filtered for some other reason?
#
if (@filteredList == $lastCount) {
# if so, put them back
#
push (@filteredList, $person);
}
} }
} }
} # if $userFlagString is valid # At this point there's no way the user wants to receive email
# about this change, so exclude them from the list of recipients.
# has the person been moved off the filtered list? push(@excludedAddresses, $user);
#
if (@filteredList == $lastCount ) {
# mark them as excluded
#
push (@excludedAddresses,$person);
}
} # for each person } # for each user on the unfiltered list
return @filteredList; return @recipients;
} }
sub NewProcessOnePerson ($$$$$$$$$$$$) { sub NewProcessOnePerson ($$$$$$$$$$$$) {
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
# Rights Reserved. # Rights Reserved.
# #
# Contributor(s): Gervase Markham <gerv@gerv.net> # Contributor(s): Gervase Markham <gerv@gerv.net>
# Myk Melez <myk@mozilla.org>
#%] #%]
[%# INTERFACE: [%# INTERFACE:
...@@ -138,7 +139,10 @@ ...@@ -138,7 +139,10 @@
{ name = 'CC', { name = 'CC',
description = 'CC field changes' }, description = 'CC field changes' },
{ name = 'Other', { name = 'Other',
description = 'Any field not mentioned above changes' } ] %] description = 'Any field not mentioned above changes' },
{ name = 'Unconfirmed',
description = 'The bug is in the unconfirmed state' },
] %]
<tr> <tr>
[% FOREACH role = [ "Reporter", "Owner", "QAcontact", "CClist", "Voter" ] [% FOREACH role = [ "Reporter", "Owner", "QAcontact", "CClist", "Voter" ]
%] %]
......
...@@ -45,7 +45,7 @@ my $defaultflagstring = "ExcludeSelf~on~"; ...@@ -45,7 +45,7 @@ my $defaultflagstring = "ExcludeSelf~on~";
my @roles = ("Owner", "Reporter", "QAcontact", "CClist", "Voter"); my @roles = ("Owner", "Reporter", "QAcontact", "CClist", "Voter");
my @reasons = ("Removeme", "Comments", "Attachments", "Status", "Resolved", my @reasons = ("Removeme", "Comments", "Attachments", "Status", "Resolved",
"Keywords", "CC", "Other"); "Keywords", "CC", "Other", "Unconfirmed");
foreach my $role (@roles) { foreach my $role (@roles) {
foreach my $reason (@reasons) { foreach my $reason (@reasons) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment