]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1062718 - add the ability to disable sending of mail when updating bugs
authorPami Ketolainen <pami.ketolainen@jollamobile.com>
Fri, 13 Mar 2015 18:23:54 +0000 (14:23 -0400)
committerDylan William Hardison <dylan@hardison.net>
Fri, 13 Mar 2015 18:27:47 +0000 (14:27 -0400)
r=dylan,a=sgreen

16 files changed:
Bugzilla/Bug.pm
Bugzilla/BugMail.pm
Bugzilla/Config/GroupSecurity.pm
Bugzilla/Constants.pm
Bugzilla/User.pm
Bugzilla/WebService/Bug.pm
attachment.cgi
process_bug.cgi
skins/standard/bug.css
template/en/default/account/prefs/email.html.tmpl
template/en/default/admin/groups/list.html.tmpl
template/en/default/admin/params/groupsecurity.html.tmpl
template/en/default/attachment/create.html.tmpl
template/en/default/attachment/edit.html.tmpl
template/en/default/bug/edit.html.tmpl
template/en/default/list/edit-multiple.html.tmpl

index 73ba62a3b80127282924952433c045be62f3f457..2bd6fb646f39d020997c7bd614406935e398ec23 100644 (file)
@@ -1265,7 +1265,7 @@ sub remove_from_db {
 #####################################################################
 
 sub send_changes {
-    my ($self, $changes, $vars) = @_;
+    my ($self, $changes, $vars, $minor_update) = @_;
 
     my $user = Bugzilla->user;
 
@@ -1283,15 +1283,15 @@ sub send_changes {
         changer   => $user,
     );
 
-    _send_bugmail({ id => $self->id, type => 'bug', forced => \%forced }, 
-                  $vars);
+    _send_bugmail({ id => $self->id, type => 'bug', forced => \%forced,
+                    minor_update => $minor_update }, $vars);
 
     # If the bug was marked as a duplicate, we need to notify users on the
     # other bug of any changes to that bug.
     my $new_dup_id = $changes->{'dup_id'} ? $changes->{'dup_id'}->[1] : undef;
     if ($new_dup_id) {
         _send_bugmail({ forced => { changer => $user }, type => "dupe",
-                        id => $new_dup_id }, $vars);
+                        id => $new_dup_id, minor_update => $minor_update }, $vars);
     }
 
     # If there were changes in dependencies, we need to notify those
@@ -1306,7 +1306,8 @@ sub send_changes {
                            type     => 'dep',
                            dep_only => 1,
                            blocker  => $self,
-                           changes  => $changes };
+                           changes  => $changes,
+                           minor_update => $minor_update };
 
             foreach my $id (@{ $self->blocked }) {
                 $params->{id} = $id;
@@ -1329,13 +1330,13 @@ sub send_changes {
 
     foreach my $id (sort { $a <=> $b } (keys %changed_deps)) {
         _send_bugmail({ forced => { changer => $user }, type => "dep",
-                         id => $id }, $vars);
+                         id => $id, minor_update => $minor_update }, $vars);
     }
 
     # Sending emails for the referenced bugs.
     foreach my $ref_bug_id (uniq @{ $self->{see_also_changes} || [] }) {
         _send_bugmail({ forced => { changer => $user },
-                        id => $ref_bug_id }, $vars);
+                        id => $ref_bug_id, minor_update => $minor_update }, $vars);
     }
 }
 
@@ -4221,6 +4222,12 @@ sub get_activity {
     return(\@operations, $incomplete_data);
 }
 
+sub has_unsent_changes {
+    my $self = shift;
+    return 1 if !defined $self->lastdiffed;
+    return datetime_from($self->lastdiffed) < datetime_from($self->delta_ts) ? 1 : 0;
+}
+
 # Update the bugs_activity table to reflect changes made in bugs.
 sub LogActivityEntry {
     my ($bug_id, $field, $removed, $added, $user_id, $timestamp, $comment_id,
@@ -4625,6 +4632,10 @@ call L<update> to make the changes permanent.
 Creates or updates a L<Bugzilla::BugUserLastVisit> for this bug and the supplied
 $user, the timestamp given as $last_visit.
 
+=item C<has_unsent_changes()>
+
+Checks if this bug has changes for which bug mail has not been sent.
+
 =back
 
 =head1 B<Methods in need of POD>
index 8b4219787d533a8cf00cc3024134a1109b5b7b48..7dfb482381860dee917e868529abf8a664af6b4f 100644 (file)
@@ -225,6 +225,9 @@ sub Send {
     my $date = $params->{dep_only} ? $end : $bug->delta_ts;
     $date = format_time($date, '%a, %d %b %Y %T %z', 'UTC');
 
+    my $minor_update = $changer->in_group(Bugzilla->params->{minor_update_group})
+                     && $params->{minor_update};
+
     foreach my $user_id (keys %recipients) {
         my %rels_which_want;
         my $user = $user_cache{$user_id} ||= new Bugzilla::User($user_id);
@@ -244,7 +247,8 @@ sub Send {
                                           $start ? \@diffs : [],
                                           $comments,
                                           $params->{dep_only},
-                                          $changer))
+                                          $changer,
+                                          $minor_update))
                 {
                     $rels_which_want{$relationship} = 
                         $recipients{$user_id}->{$relationship};
index e827834a0b1e3df2859c3ecad419f910c9281a42..4fa21e72f42b392b772901b5a4ba7c6ca399e7ed 100644 (file)
@@ -66,6 +66,14 @@ sub get_param_list {
    checker => \&check_comment_taggers_group
   },
 
+  {
+   name => 'minor_update_group',
+   type => 's',
+   choices => \&_get_all_group_names,
+   default => '',
+   checker => \&check_group
+  },
+
   {
    name => 'debug_group',
    type => 's',
index 414cd2fed2290e7f56fde82c7c129de7f1c36f93..323fb151cbc93ce37689b3600e03da82f82cfac7 100644 (file)
@@ -94,7 +94,7 @@ use Memoize;
     EVT_BUG_CREATED EVT_COMPONENT
 
     NEG_EVENTS
-    EVT_UNCONFIRMED EVT_CHANGED_BY_ME 
+    EVT_UNCONFIRMED EVT_CHANGED_BY_ME EVT_MINOR_UPDATE
         
     GLOBAL_EVENTS
     EVT_FLAG_REQUESTED EVT_REQUESTED_FLAG
@@ -384,8 +384,9 @@ use constant POS_EVENTS => EVT_OTHER, EVT_ADDED_REMOVED, EVT_COMMENT,
 
 use constant EVT_UNCONFIRMED        => 50;
 use constant EVT_CHANGED_BY_ME      => 51;
+use constant EVT_MINOR_UPDATE       => 52;
 
-use constant NEG_EVENTS => EVT_UNCONFIRMED, EVT_CHANGED_BY_ME;
+use constant NEG_EVENTS => EVT_UNCONFIRMED, EVT_CHANGED_BY_ME, EVT_MINOR_UPDATE;
 
 # These are the "global" flags, which aren't tied to a particular relationship.
 # and so use REL_ANY.
index b28d0932365d0d9890fdfe9991547cddfb0c8fe2..fdc54de04edb04a64117f61bb2639451068d7a05 100644 (file)
@@ -2037,7 +2037,8 @@ our %names_to_events = (
 # Note: the "+" signs before the constants suppress bareword quoting.
 sub wants_bug_mail {
     my $self = shift;
-    my ($bug, $relationship, $fieldDiffs, $comments, $dep_mail, $changer) = @_;
+    my ($bug, $relationship, $fieldDiffs, $comments, $dep_mail, $changer,
+        $minor_update) = @_;
 
     # Make a list of the events which have happened during this bug change,
     # from the point of view of this user.    
@@ -2115,6 +2116,10 @@ sub wants_bug_mail {
     if ($wants_mail && $bug->bug_status eq 'UNCONFIRMED') {
         $wants_mail &= $self->wants_mail([EVT_UNCONFIRMED], $relationship);
     }
+
+    if ($wants_mail && $minor_update) {
+        $wants_mail &= $self->wants_mail([EVT_MINOR_UPDATE], $relationship);
+    }
     
     return $wants_mail;
 }
index 23d385cd4b5426a9dc31b2fe5d8a22fa49b62269..b3cb631fb2a56e1b63c04f6138fd33f84fc48cf5 100644 (file)
@@ -644,6 +644,7 @@ sub update {
 
     my @bugs = map { Bugzilla::Bug->check_for_edit($_) } @$ids;
 
+    my $minor_update = delete $params->{minor_update} ? 1 : 0;
     my %values = %$params;
     $values{other_bugs} = \@bugs;
 
@@ -677,14 +678,16 @@ sub update {
     }
 
     my %all_changes;
+    my %minor_updates;
     $dbh->bz_start_transaction();
     foreach my $bug (@bugs) {
+        $minor_updates{$bug->id} = $bug->has_unsent_changes ? 0 : $minor_update;
         $all_changes{$bug->id} = $bug->update();
     }
     $dbh->bz_commit_transaction();
 
     foreach my $bug (@bugs) {
-        $bug->send_changes($all_changes{$bug->id});
+        $bug->send_changes($all_changes{$bug->id}, undef, $minor_updates{$bug->id});
     }
 
     my %api_name = reverse %{ Bugzilla::Bug::FIELD_MAP() };
@@ -820,6 +823,7 @@ sub add_attachment {
         || ThrowCodeError('param_required', { param => 'data' });
 
     my @bugs = map { Bugzilla::Bug->check_for_edit($_) } @{ $params->{ids} };
+    my $minor_update = delete $params->{minor_update} ? 1 : 0;
 
     my @created;
     $dbh->bz_start_transaction();
@@ -863,10 +867,17 @@ sub add_attachment {
               extra_data  => $attachment->id });
         push(@created, $attachment);
     }
-    $_->bug->update($timestamp) foreach @created;
+    my %minor_updates;
+    foreach my $attachment (@created) {
+        my $bug = $attachment->bug;
+        $minor_updates{$bug->id} = $bug->has_unsent_changes ? 0 : $minor_update;
+        $bug->update($timestamp);
+    }
     $dbh->bz_commit_transaction();
 
-    $_->send_changes() foreach @bugs;
+    foreach my $bug (@bugs) {
+        $bug->send_changes(undef, undef, $minor_updates{$bug->id});
+    }
 
     my @created_ids = map { $_->id } @created;
 
@@ -882,6 +893,7 @@ sub update_attachment {
     my $ids = delete $params->{ids};
     defined $ids || ThrowCodeError('param_required', { param => 'ids' });
 
+    my $req_minor_update = delete $params->{minor_update} ? 1 : 0;
     # Some fields cannot be sent to set_all
     foreach my $key (qw(login password token)) {
         delete $params->{$key};
@@ -967,8 +979,9 @@ sub update_attachment {
 
     # Email users about the change
     foreach my $bug (values %bugs) {
+        my $minor_update = $bug->has_unsent_changes ? 0 : $req_minor_update;
         $bug->update();
-        $bug->send_changes();
+        $bug->send_changes(undef, undef, $minor_update);
     }
 
     # Return the information to the user
@@ -989,6 +1002,8 @@ sub add_comment {
         || ThrowCodeError('param_required', { param => 'comment' });
     
     my $bug = Bugzilla::Bug->check_for_edit($params->{id});
+    my $minor_update = delete $params->{minor_update} ? 1 : 0;
+    $minor_update = $bug->has_unsent_changes ? 0 : $minor_update;
 
     # Backwards-compatibility for versions before 3.6    
     if (defined $params->{private}) {
@@ -1007,7 +1022,8 @@ sub add_comment {
     my $new_comment_id = $bug->{added_comments}[0]->id;
 
     # Send mail.
-    Bugzilla::BugMail::Send($bug->bug_id, { changer => $user });
+    Bugzilla::BugMail::Send($bug->bug_id, { changer => $user },
+            { minor_update => $minor_update });
 
     return { id => $self->type('int', $new_comment_id) };
 }
@@ -1023,6 +1039,7 @@ sub update_see_also {
     my ($add, $remove) = @$params{qw(add remove)};
     ($add || $remove)
         or ThrowCodeError('params_required', { params => ['add', 'remove'] });
+    my $req_minor_update = delete $params->{minor_update} ? 1 : 0;
 
     my @bugs;
     foreach my $id (@{ $params->{ids} }) {
@@ -1038,6 +1055,7 @@ sub update_see_also {
     
     my %changes;
     foreach my $bug (@bugs) {
+        my $minor_update = $bug->has_unsent_changes ? 0 : $req_minor_update;
         my $change = $bug->update();
         if (my $see_also = $change->{see_also}) {
             $changes{$bug->id}->{see_also} = {
@@ -1050,7 +1068,8 @@ sub update_see_also {
             $changes{$bug->id}->{see_also} = { added => [], removed => [] };
         }
 
-        Bugzilla::BugMail::Send($bug->id, { changer => $user });
+        Bugzilla::BugMail::Send($bug->id, { changer => $user },
+                { minor_update => $minor_update });
     }
 
     return { changes => \%changes };
@@ -3414,6 +3433,12 @@ C<string> The login of the requestee if the flag type is requestable to a specif
 
 =back
 
+=item C<minor_update>
+
+C<boolean> If set to true, this is considered a minor update and no mail is sent
+to users who do not want minor update emails. If current user is not in the
+minor_update_group, this parameter is simply ignored.
+
 =back
 
 =item B<Returns>
@@ -3609,6 +3634,14 @@ C<boolean> Set to true if you specifically want a new flag to be created.
 
 =back
 
+=item C<minor_update>
+
+C<boolean> If set to true, this is considered a minor update and no mail is sent
+to users who do not want minor update emails. If current user is not in the
+minor_update_group, this parameter is simply ignored.
+
+=back
+
 =item B<Returns>
 
 A C<hash> with a single field, "attachments". This points to an array of hashes
@@ -3729,8 +3762,6 @@ You did not specify a value for the C<summary> argument.
 
 =back
 
-=back
-
 =head2 add_comment
 
 B<STABLE>
@@ -3771,6 +3802,9 @@ structures, otherwise it is a normal text.
 on the bug. If you are not in the time tracking group, this value will
 be ignored.
 
+=item C<minor_update> (boolean) - If set to true, this is considered a minor update
+and no mail is sent to users who do not want minor update emails. If current user
+is not in the minor_update_group, this parameter is simply ignored.
 
 =back
 
@@ -3872,6 +3906,12 @@ pulled from the URL path.
 Array of C<int>s or C<string>s. The ids or aliases of the bugs that
 you want to modify.
 
+=item C<minor_update>
+
+C<boolean> If set to true, this is considered a minor update and no mail is sent
+to users who do not want minor update emails. If current user is not in the
+minor_update_group, this parameter is simply ignored.
+
 =back
 
 B<Note>: All following fields specify the values you want to set on the
@@ -4442,6 +4482,12 @@ If you specify a URL that is not in the See Also field of a particular bug,
 it will just be silently ignored. Invaild URLs are currently silently ignored,
 though this may change in some future version of Bugzilla.
 
+=item C<minor_update>
+
+C<boolean> If set to true, this is considered a minor update and no mail is sent
+to users who do not want minor update emails. If current user is not in the
+minor_update_group, this parameter is simply ignored.
+
 =back
 
 NOTE: If you specify the same URL in both C<add> and C<remove>, it will
index 61e6f58d8dfd1acd6cf23297274b107446667f95..7df230d793a8c4e264d1efa4964c77c47aae944b 100755 (executable)
@@ -511,6 +511,9 @@ sub insert {
         @obsolete_attachments = Bugzilla::Attachment->validate_obsolete($bug, \@obsolete);
     }
 
+    my $minor_update = $cgi->param('minor_update') ? 1 : 0;
+    $minor_update = $bug->has_unsent_changes ? 0 : $minor_update;
+
     # Must be called before create() as it may alter $cgi->param('ispatch').
     my $content_type = Bugzilla::Attachment::get_content_type();
 
@@ -586,7 +589,8 @@ sub insert {
     $vars->{'contenttypemethod'} = $cgi->param('contenttypemethod');
 
     my $recipients = { 'changer' => $user, 'owner' => $owner };
-    $vars->{'sent_bugmail'} = Bugzilla::BugMail::Send($bugid, $recipients);
+    my $params = { 'minor_update' => $minor_update };
+    $vars->{'sent_bugmail'} = Bugzilla::BugMail::Send($bugid, $recipients, $params);
 
     print $cgi->header();
     # Generate and return the UI (HTML page) from the appropriate template.
@@ -677,6 +681,9 @@ sub update {
     my $token = $cgi->param('token');
     check_hash_token($token, [$attachment->id, $attachment->modification_time]);
 
+    my $minor_update = $cgi->param('minor_update') ? 1 : 0;
+    $minor_update = $bug->has_unsent_changes ? 0 : $minor_update;
+
     # If the user submitted a comment while editing the attachment,
     # add the comment to the bug. Do this after having validated isprivate!
     my $comment = $cgi->param('comment');
@@ -739,7 +746,8 @@ sub update {
     $vars->{'bugs'} = [$bug];
     $vars->{'header_done'} = 1;
     $vars->{'sent_bugmail'} = 
-        Bugzilla::BugMail::Send($bug->id, { 'changer' => $user });
+        Bugzilla::BugMail::Send($bug->id, { 'changer' => $user },
+            {'minor_update' => $minor_update });
 
     print $cgi->header();
 
index b3d9799602afa9758b2f9ffe9481a310ffed6a10..448b42c408bebae12804a103fe1d1a45fbbe4105 100755 (executable)
@@ -373,7 +373,9 @@ else {
 ##############################
 # Do Actual Database Updates #
 ##############################
+my $req_minor_update = $cgi->param('minor_update') ? 1 : 0;
 foreach my $bug (@bug_objects) {
+    my $minor_update = $bug->has_unsent_changes ? 0 : $req_minor_update;
     my $changes = $bug->update();
 
     if ($changes->{'bug_status'}) {
@@ -386,7 +388,7 @@ foreach my $bug (@bug_objects) {
         }
     }
 
-    $bug->send_changes($changes, $vars);
+    $bug->send_changes($changes, $vars, $minor_update);
 }
 
 # Delete the session token used for the mass-change.
index 851b1bdbab092210be21b5ceaecd53362c0209e1..35d169c1e8d21979e0566815f60fd24c95903012 100644 (file)
@@ -226,6 +226,9 @@ table#flags {
 
 .knob-buttons {
     float: right;
+    text-align: right;
+    font-size: small;
+    font-weight: normal;
 }
 
 .text_input, .bz_userfield, #keywords_container, #tag_container {
index 05248417435750c5a405db4bbeb695821d0c7031..ab25ff8bb5c137eb9b741f6e79a28c7862e793bf 100644 (file)
@@ -123,6 +123,8 @@ function SetCheckboxes(setting) {
       description = "The $terms.bug is in the UNCONFIRMED state" },
     { id = constants.EVT_CHANGED_BY_ME,
       description = "The change was made by me" },
+    { id = constants.EVT_MINOR_UPDATE,
+      description = "The change was marked as a minor update" },
 ] %]
 
 [% relationships = [
index 673c053cba14a8d980b449dc6b616b971597a791..33732f957e0ea128ec0c02003f3d092b892ac994 100644 (file)
@@ -76,7 +76,8 @@
 %]
 
 [% FOREACH group IN ["chartgroup", "comment_taggers_group", "debug_group",
-                     "insidergroup", "querysharegroup", "timetrackinggroup"] %]
+                     "insidergroup", "minor_update_group", "querysharegroup",
+                     "timetrackinggroup"] %]
   [% special_group = Param(group) %]
 
   [% IF special_group %]
index 590f4da029bf19d7aadc98b60412425bb6790d23..19d78de5a63e9df9cc2807b19fe886ab67f32fa3 100644 (file)
               "view it. If it is off, a user needs to be a member of all " _
               "the $terms.bug's groups. Note that in either case, if the " _
               "user has a role on the $terms.bug (e.g. reporter) that may " _
-              "also affect their permissions."
+              "also affect their permissions.",
+
+  minor_update_group => "The name of the group of users who are allowed to " _
+                        "use the 'minor update'-option on $terms.bug changes " _
+                        "to limit mail sending. " _
+                        "Setting this to empty disables the feature.",
  }
 %]
index e566b428eed1b8af2356c21ebafb3320b315b4cf..05223ede4b165df513f0a6ff4e2d45143f038afc 100644 (file)
@@ -119,6 +119,17 @@ TUI_hide_default('attachment_text_field');
 
     [% Hook.process('form_before_submit') %]
 
+    [% IF Param('minor_update_group') && user.in_group(Param('minor_update_group')) %]
+      <tr>
+        <th>&nbsp;</th>
+        <td>
+          <input type="checkbox" name="minor_update" value="1">
+          <label class="" for="minor_update">
+            This is a minor update (do not send email)
+          </label>
+        </td>
+      </tr>
+    [% END %]
     <tr>
       <th>&nbsp;</th>
       <td><input type="submit" id="create" value="Submit"></td>
index 184cdde054283f970c7e265d7ea0a530946409e8..d2554dfb82030af06d43bc205f7ec9db7086c984 100644 (file)
 
         [% IF user.id %]       
           <div id="update_container">
+            [% IF Param('minor_update_group') && user.in_group(Param('minor_update_group')) %]
+              <input type="checkbox" name="minor_update" value="1">
+              <label class="" for="minor_update">
+                This is a minor update (do not send email)
+              </label><br>
+            [% END %]
             <input type="submit" value="Submit" id="update">
           </div>
         [% END %]        
index 6bb75b985ecc58fd2a72973487828d3be628fa4f..f23c6b85cf558bd6280ff6c225e5834cbfb807f7 100644 (file)
     <div class="knob-buttons">
       <input type="submit" value="Save Changes" 
              id="commit[% id FILTER css_class_quote %]">
+      [% IF Param('minor_update_group') && user.in_group(Param('minor_update_group')) %]
+        <br>
+        <label class="" for="minor_update">
+          This is a minor update (do not send email)
+        </label>
+        <input type="checkbox" name="minor_update" value="1">
+      [% END %]
     </div>
   [% END %]
 [% END %]
index d956fa62ba7187d023c98543876fe337e344d172..4ef067201ec7a4bc9a1f9699e7ece4de5e140218 100644 (file)
 [%+ Hook.process('after_groups') %]
 
 <input type="submit" id="commit" value="Commit">
+[% IF Param('minor_update_group') && user.in_group(Param('minor_update_group')) %]
+  <br>
+  <input type="checkbox" name="minor_update" value="1">
+  <label for="minor_update">
+    This is a minor update (do not send email)
+  </label>
+[% END %]
 
 [%############################################################################%]
 [%# Select Menu Block                                                        #%]