summaryrefslogtreecommitdiffstats
path: root/processmail
diff options
context:
space:
mode:
Diffstat (limited to 'processmail')
-rwxr-xr-xprocessmail278
1 files changed, 125 insertions, 153 deletions
diff --git a/processmail b/processmail
index a4c7bdc5e..37036f279 100755
--- a/processmail
+++ b/processmail
@@ -38,6 +38,7 @@ use RelationSet;
sub processmail_sillyness {
my $zz;
$zz = $::db;
+ $zz = $::unconfirmedstate;
}
$| = 1;
@@ -232,7 +233,10 @@ sub ProcessOneBug {
#
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) = ();
#open(LOG, ">>/tmp/maillog");
@@ -401,12 +405,17 @@ sub filterExcludeList ($$) {
# if no flags are set and there was some other field change
# set the Status flag
#
-sub getEmailAttributes ($@) {
+sub getEmailAttributes (\%\@$) {
- my ($commentField,@fieldDiffs) = @_;
+ my ($bug, $fieldDiffs, $commentField) = @_;
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);
#print qq{field: $fieldName $new<br>};
@@ -448,7 +457,7 @@ sub getEmailAttributes ($@) {
}
# default fallthrough for any unflagged change is 'Other'
- if ( @flags == 0 && @fieldDiffs != 0 ) {
+ if ( @flags == 0 && @$fieldDiffs != 0 ) {
push (@flags, 'Other');
}
@@ -470,168 +479,131 @@ sub getEmailAttributes ($@) {
}
sub filterEmailGroup ($$$) {
+ # This function figures out who should receive email about the bug
+ # based on the user's role with regard to the bug (assignee, reporter
+ # etc.), the changes that occurred (new comments, attachment added,
+ # status changed etc.) and the user's email preferences.
- my ($emailGroup,$refAttributes,$emailList) = @_;
- my @emailAttributes = @$refAttributes;
- my @emailList = split(/,/,$emailList);
- 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
+ # not receive email about them to the global @excludedAddresses list.
-
- # the force list for this email group needs to be checked as well
- #
- push @emailList, @{$force{$emailGroup}};
-
- # Check this user for any watchers... doing this here allows them to inhert the
- # relationship to the bug of the person they are watching (if the person they
- # are watching is an owner, their mail is filtered as if they were the owner).
- if (Param("supportwatchers")) {
- my @watchers;
- foreach my $person(@emailList) {
- my $personId = DBname_to_id($person);
- SendSQL("SELECT watcher FROM watch WHERE watched = $personId");
- while(MoreSQLData()) {
- my ($watcher) = FetchSQLData();
- if ($watcher) {
- push (@watchers, DBID_to_name($watcher));
- }
- }
- }
- push(@emailList, @watchers);
- }
-
-
- foreach my $person (@emailList) {
+ my ($role, $reasons, $users) = @_;
+
+ # Make a list of users to filter.
+ my @users = split( /,/ , $users );
+
+ # Treat users who are in the process of being removed from this role
+ # as if they were still in it.
+ push @users, @{$force{$role}};
+
+ # If this installation supports user watching, add to the list those
+ # users who are watching other users already on the list. By doing
+ # this here, we allow watchers to inherit the roles of the people
+ # they are watching while at the same time filtering email for watchers
+ # 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.
+ 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)
+ AND watched.userid = watch.watched
+ AND watch.watcher = watchers.userid");
+ push (@users, FetchOneColumn()) while MoreSQLData();
+ }
+
+ # Initialize the list of recipients.
+ my @recipients = ();
+
+ USER: foreach my $user (@users) {
+ next unless $user;
- my $lastCount = @filteredList;
-
- if ( $person eq '' ) { next; }
-
- my $userid = DBname_to_id($person);
-
- if ( ! $userid ) {
- push(@filteredList,$person);
+ # 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;
}
- SendSQL("SELECT emailflags FROM profiles WHERE " .
- "userid = $userid" );
-
- my ($userFlagString) = FetchSQLData();
+ # Get the user's email preferences from the database.
+ SendSQL("SELECT emailflags FROM profiles WHERE userid = $userid");
+ my $prefs = FetchOneColumn();
- # If the sender doesn't want email, exclude them from list
+ # 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;
+ }
- if (lc($person) eq $nametoexclude) {
-
- if ( defined ($userFlagString) &&
- $userFlagString =~ /ExcludeSelf\~on/ ) {
-
- push (@excludedAddresses,$person);
- next;
- }
+ # 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);
+
+ # 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,
+ # filter them from the list.
+ if (lc($user) eq $nametoexclude && $prefs{'ExcludeSelf'} eq 'on') {
+ push(@excludedAddresses, $user);
+ next;
}
- # if the users database entry is empty, send them all email
- # by default (they have not accessed userprefs.cgi recently).
+ # If the user doesn't want to receive email about unconfirmed
+ # bugs, that setting overrides their other preferences, including
+ # 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;
+ }
- if ( !defined($userFlagString) || !($userFlagString =~ /email/) ) {
- push(@filteredList,$person);
+ # If the user was added to or removed from this role, and they
+ # prefer to receive email when that happens, send them mail.
+ # Note: This was originally written to send email when users
+ # were removed from roles and was later enhanced for additions,
+ # but for simplicity's sake the name "Removeme" was retained.
+ if (grep($_ eq $user, @{$force{$role}})
+ && $prefs{"email${role}Removeme"} eq 'on')
+ {
+ push (@recipients, $user);
+ next;
}
- 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);
-
- my $detectedOn = 0;
-
- foreach my $attribute (@emailAttributes) {
-
- my $matchName = 'email' . $emailGroup . $attribute;
-
- # **** 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;
- }
-
- if ($flagName eq $matchName){
- if ($flagValue eq 'on') {
- $detectedOn = 1;
- }
- }
-
- } # for each userFlag
-
- } # for each email attribute
-
- # if the current flag hasn't been detected on at least once,
- # this person gets filtered from this group.
- #
- if (! $detectedOn) {
- pop(@filteredList);
- }
-
- # check to see if the person was added to or removed from
- # this email group.
- # Note: This was originally written as only removed from
- # and was rewritten to be Added/Removed, but for simplicity
- # sake, the name "Removeme" wasn't changed.
- # http://bugzilla.mozilla.org/show_bug.cgi?id=71912
-
- if ( grep ($_ eq $person, @{$force{$emailGroup}} ) ) {
-
- # if so, see if they want mail about that
- #
- 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 the user prefers to be included in mail about this change,
+ # or they haven't specified a preference for it (because they
+ # haven't visited the email preferences page since the preference
+ # was added, in which case we include them by default), add them
+ # to the list of recipients.
+ foreach my $reason (@$reasons) {
+ my $pref = "email$role$reason";
+ if (!exists($prefs{$pref}) || $prefs{$pref} eq 'on') {
+ push(@recipients, $user);
+ next USER;
}
+ }
+
+ # At this point there's no way the user wants to receive email
+ # about this change, so exclude them from the list of recipients.
+ push(@excludedAddresses, $user);
+
+ } # for each user on the unfiltered list
- } # if $userFlagString is valid
-
- # has the person been moved off the filtered list?
- #
- if (@filteredList == $lastCount ) {
-
- # mark them as excluded
- #
- push (@excludedAddresses,$person);
- }
-
- } # for each person
-
- return @filteredList;
+ return @recipients;
}
sub NewProcessOnePerson ($$$$$$$$$$$$) {