]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1105568: Add support for HTML flagmail
authorEd Morley <emorley@mozilla.com>
Thu, 19 Mar 2015 07:16:30 +0000 (15:16 +0800)
committerByron Jones <glob@mozilla.com>
Thu, 19 Mar 2015 07:16:30 +0000 (15:16 +0800)
r=glob,a=glob

Bugzilla/BugMail.pm
Bugzilla/Flag.pm
Bugzilla/Mailer.pm
Bugzilla/Product.pm
template/en/default/email/flagmail-header.txt.tmpl [new file with mode: 0644]
template/en/default/email/flagmail.html.tmpl [new file with mode: 0644]
template/en/default/email/flagmail.txt.tmpl

index df39bd108af96f0cc3ceb932fc6a5c495ff8f12f..f655c4ae6b3adb60c7afeef9c7741a5fc45b8819 100644 (file)
@@ -437,45 +437,12 @@ sub _flatten_object {
 
 sub _generate_bugmail {
     my ($vars) = @_;
-    my $user = $vars->{to_user};
-    my $template = Bugzilla->template_inner($user->setting('lang'));
-    my ($msg_text, $msg_html, $msg_header);
-
-    $template->process("email/bugmail-header.txt.tmpl", $vars, \$msg_header)
-        || ThrowTemplateError($template->error());
-    $template->process("email/bugmail.txt.tmpl", $vars, \$msg_text)
-        || ThrowTemplateError($template->error());
-
-    my @parts = (
-        Email::MIME->create(
-            attributes => {
-                content_type => "text/plain",
-            },
-            body => $msg_text,
-        )
-    );
-    if ($user->setting('email_format') eq 'html') {
-        $template->process("email/bugmail.html.tmpl", $vars, \$msg_html)
-            || ThrowTemplateError($template->error());
-        push @parts, Email::MIME->create(
-            attributes => {
-                content_type => "text/html",         
-            },
-            body => $msg_html,
-        );
-    }
-
-    # TT trims the trailing newline, and threadingmarker may be ignored.
-    my $email = new Email::MIME("$msg_header\n");
-    if (scalar(@parts) == 1) {
-        $email->content_type_set($parts[0]->content_type);
-    } else {
-        $email->content_type_set('multipart/alternative');
-        # Some mail clients need same encoding for each part, even empty ones.
-        $email->charset_set('UTF-8');
-    }
-    $email->parts_set(\@parts);
-    return $email;
+    my $templates = {
+        header => "email/bugmail-header.txt.tmpl",
+        text   => "email/bugmail.txt.tmpl",
+        html   => "email/bugmail.html.tmpl",
+    };
+    return generate_email($vars, $templates);
 }
 
 sub _get_diffs {
index 50474b8855f9322825e5ea16191db2fca0de591c..6d056e7e6fe9d38c0d3291f13302204e43b1ab15 100644 (file)
@@ -1116,13 +1116,6 @@ sub notify {
     if ($addressee && $addressee->email_enabled) {
         $recipients{$addressee->email} = $addressee;
     }
-    # Process and send notification for each recipient.
-    # If there are users in the CC list who don't have an account,
-    # use the default language for email notifications.
-    my $default_lang;
-    if (grep { !$_ } values %recipients) {
-        $default_lang = Bugzilla::User->new()->setting('lang');
-    }
 
     # Get comments on the bug
     my $all_comments = $bug->comments({ after => $bug->lastdiffed });
@@ -1132,18 +1125,20 @@ sub notify {
     my $public_comments = [ grep { !$_->is_private } @$all_comments ];
 
     foreach my $to (keys %recipients) {
+        my $user = $recipients{$to};
         # 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;
+        my $thread_user_id = $user ? $user->id : 0;
 
         # We only want to show private comments to users in the is_insider group
-        my $comments = $recipients{$to} && $recipients{$to}->is_insider
+        my $comments = $user && $user->is_insider
             ? $all_comments : $public_comments;
 
         my $vars = {
             flag            => $flag,
             old_flag        => $old_flag,
             to              => $to,
+            to_user         => $user,
             date            => $timestamp,
             bug             => $bug,
             attachment      => $attachment,
@@ -1151,15 +1146,13 @@ sub notify {
             new_comments    => $comments,
         };
 
-        my $lang = $recipients{$to} ?
-          $recipients{$to}->setting('lang') : $default_lang;
-
-        my $template = Bugzilla->template_inner($lang);
-        my $message;
-        $template->process("email/flagmail.txt.tmpl", $vars, \$message)
-          || ThrowTemplateError($template->error());
+        my $templates = {
+            header => "email/flagmail-header.txt.tmpl",
+            text   => "email/flagmail.txt.tmpl",
+            html   => "email/flagmail.html.tmpl",
+        };
 
-        MessageToMTA($message);
+        MessageToMTA(generate_email($vars, $templates));
     }
 }
 
index ef75d0cf888b7433e824b221e80b4c2624fcfcba..4f13f77d25a96bab52910a6a7b3515e8d52c6efe 100644 (file)
@@ -12,11 +12,12 @@ use strict;
 use warnings;
 
 use parent qw(Exporter);
-@Bugzilla::Mailer::EXPORT = qw(MessageToMTA build_thread_marker);
+@Bugzilla::Mailer::EXPORT = qw(MessageToMTA build_thread_marker generate_email);
 
 use Bugzilla::Constants;
 use Bugzilla::Error;
 use Bugzilla::Hook;
+use Bugzilla::User;
 use Bugzilla::Util;
 
 use Date::Format qw(time2str);
@@ -28,6 +29,63 @@ use Email::Sender::Simple qw(sendmail);
 use Email::Sender::Transport::SMTP::Persistent;
 use Bugzilla::Sender::Transport::Sendmail;
 
+sub generate_email {
+    my ($vars, $templates) = @_;
+    my ($lang, $email_format, $msg_text, $msg_html, $msg_header);
+
+    if ($vars->{to_user}) {
+      $lang = $vars->{to_user}->setting('lang');
+      $email_format = $vars->{to_user}->setting('email_format');
+    } else {
+      # If there are users in the CC list who don't have an account,
+      # use the default language for email notifications.
+      $lang = Bugzilla::User->new()->setting('lang');
+      # However we cannot fall back to the default email_format, since
+      # it may be HTML, and many of the includes used in the HTML
+      # template require a valid user object. Instead we fall back to
+      # the plaintext template.
+      $email_format = 'text_only';
+    }
+
+    my $template = Bugzilla->template_inner($lang);
+
+    $template->process($templates->{header}, $vars, \$msg_header)
+        || ThrowTemplateError($template->error());
+    $template->process($templates->{text}, $vars, \$msg_text)
+        || ThrowTemplateError($template->error());
+
+    my @parts = (
+        Email::MIME->create(
+            attributes => {
+                content_type => "text/plain",
+            },
+            body => $msg_text,
+        )
+    );
+    if ($templates->{html} && $email_format eq 'html') {
+        $template->process($templates->{html}, $vars, \$msg_html)
+            || ThrowTemplateError($template->error());
+        push @parts, Email::MIME->create(
+            attributes => {
+                content_type => "text/html",
+            },
+            body => $msg_html,
+        );
+    }
+
+    # TT trims the trailing newline, and threadingmarker may be ignored.
+    my $email = new Email::MIME("$msg_header\n");
+    if (scalar(@parts) == 1) {
+        $email->content_type_set($parts[0]->content_type);
+    } else {
+        $email->content_type_set('multipart/alternative');
+        # Some mail clients need same encoding for each part, even empty ones.
+        $email->charset_set('UTF-8') if Bugzilla->params->{'utf8'};
+    }
+    $email->parts_set(\@parts);
+    return $email;
+}
+
 sub MessageToMTA {
     my ($msg, $send_now) = (@_);
     my $method = Bugzilla->params->{'mail_delivery_method'};
@@ -285,6 +343,10 @@ Bugzilla::Mailer - Provides methods for sending email
 
 =over
 
+=item C<generate_email>
+
+Generates a multi-part email message, using the supplied list of templates.
+
 =item C<MessageToMTA>
 
 Sends the passed message to the mail transfer agent.
index 30ebc7c6cd564080589ad04db4aedcb59d63290a..0c0cb458d554b2def12164e35d848d8a4c9583de 100644 (file)
@@ -22,7 +22,6 @@ use Bugzilla::Milestone;
 use Bugzilla::Field;
 use Bugzilla::Status;
 use Bugzilla::Install::Requirements;
-use Bugzilla::Mailer;
 use Bugzilla::Series;
 use Bugzilla::Hook;
 use Bugzilla::FlagType;
diff --git a/template/en/default/email/flagmail-header.txt.tmpl b/template/en/default/email/flagmail-header.txt.tmpl
new file mode 100644 (file)
index 0000000..8aa3955
--- /dev/null
@@ -0,0 +1,28 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+  # License, v. 2.0. If a copy of the MPL was not distributed with this
+  # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+  #
+  # This Source Code Form is "Incompatible With Secondary Licenses", as
+  # defined by the Mozilla Public License, v. 2.0.
+  #%]
+
+[% flagtype_name = flag ? flag.type.name : old_flag.type.name %]
+[% statuses = { '+' => "granted" , '-' => 'denied' , 'X' => "canceled" ,
+                '?' => "asked" } %]
+
+[% action = flag.status || 'X' %]
+
+[% IF flag && flag.status == '?' %]
+  [% subject_status = "requested" %]
+[% ELSE %]
+  [% subject_status = statuses.$action %]
+[% END %]
+From: [% Param('mailfrom') %]
+To: [% to %]
+Subject: [% flagtype_name %] [%+ subject_status %]: [[% terms.Bug %] [%+ bug.bug_id %]] [% bug.short_desc %]
+[%- IF attachment %] :
+  [Attachment [% attachment.id %]] [% attachment.description FILTER clean_text %][% END %]
+Date: [% date %]
+X-Bugzilla-Type: request
+[%+ INCLUDE "email/header-common.txt.tmpl" %]
+[%+ threadingmarker %]
diff --git a/template/en/default/email/flagmail.html.tmpl b/template/en/default/email/flagmail.html.tmpl
new file mode 100644 (file)
index 0000000..314455c
--- /dev/null
@@ -0,0 +1,80 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+  # License, v. 2.0. If a copy of the MPL was not distributed with this
+  # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+  #
+  # This Source Code Form is "Incompatible With Secondary Licenses", as
+  # defined by the Mozilla Public License, v. 2.0.
+  #%]
+
+[% flagtype_name = flag ? flag.type.name : old_flag.type.name %]
+[% statuses = { '+' => "granted" , '-' => 'denied' , 'X' => "canceled" ,
+                '?' => "asked" } %]
+
+[% action = flag.status || 'X' %]
+
+[% pending_request = (flag && flag.status == '?') %]
+[% reassigned = (pending_request && flag.setter_id != user.id) %]
+[% was_pending_request = (old_flag && old_flag.status == '?') %]
+
+<html>
+  <head>
+    <base href="[% urlbase FILTER html %]">
+  </head>
+  <body>
+    <p>
+      [% INCLUDE global/user.html.tmpl user = to_user, who = user %] has
+      [% IF reassigned =%]
+        reassigned [% INCLUDE global/user.html.tmpl user = to_user, who = flag.setter %]'s request for
+        [% IF old_flag.requestee.defined %]
+          [%= INCLUDE global/user.html.tmpl user = to_user, who = old_flag.requestee %]'s
+        [% END %]
+        [%= flagtype_name FILTER html %]
+        [% IF flag.requestee.defined =%]
+          to [% INCLUDE global/user.html.tmpl user = to_user, who = flag.requestee %]
+        [% END %]
+      [% ELSE %]
+        [%= statuses.$action FILTER html %]
+        [% IF pending_request %]
+          [%= INCLUDE global/user.html.tmpl user = to_user, who = flag.requestee %] for
+        [% ELSIF was_pending_request %]
+          [%= INCLUDE global/user.html.tmpl user = to_user, who = old_flag.setter %]'s request for
+          [% IF old_flag.requestee.defined %]
+            [%= INCLUDE global/user.html.tmpl user = to_user, who = old_flag.requestee %]'s
+          [% END %]
+        [% END %]
+        <b>[% flagtype_name FILTER html %]</b>
+      [% END %]:
+    </p>
+
+    <p>
+      [% "$terms.Bug $bug.bug_id" FILTER bug_link(bug, {full_url => 1, user => to_user}) FILTER none %]:
+      [%= bug.short_desc FILTER html %]
+    </p>
+
+    [% IF attachment %]
+      <p>
+        <a href="[% urlbase FILTER html %]attachment.cgi?id=[% attachment.id FILTER html ~%]
+                 &action=edit">Attachment [% attachment.id FILTER html %]</a>:
+        [%= attachment.description FILTER html %]
+      </p>
+    [% END %]
+
+    [% Hook.process('after_summary') %]
+
+    <p>
+      [% FOREACH comment = new_comments %]
+        <div>
+          [% IF comment.count %]
+            <b>[% "Comment # ${comment.count}" FILTER bug_link(bug,
+                {comment_num => comment.count, full_url => 1, user => to_user}) FILTER none =%]
+            on [% "$terms.bug $bug.id" FILTER bug_link(bug, { full_url => 1, user => to_user }) FILTER none =%]
+            from [% INCLUDE global/user.html.tmpl user = to_user, who = comment.author %]</b>
+          [% ELSE %]
+            <b>Description:</b>
+          [% END %]
+          <pre>[% comment.body_full({ wrap => 1 }) FILTER markdown(bug, comment, to_user) %]</pre>
+        </div>
+      [% END %]
+    </p>
+  </body>
+</html>
index cf64d9661354141f93e894dcdb30892ff8fcc493..9b80a493d6f2e90fa6ecdd8e9a2eb1e20bf505e1 100644 (file)
@@ -17,7 +17,6 @@
 [% action = flag.status || 'X' %]
 
 [% IF flag && flag.status == '?' %]
-  [% subject_status = "requested" %]
   [% IF flag.setter_id == user.id %]
     [% to_identity = flag.requestee.identity _ " for" %]
   [% ELSE %]
         [% requestee_identity = old_flag.requestee.identity _ "'s" %]
     [% END %]
   [% END %]
-  [% subject_status = statuses.$action %]
 [% END %]
-From: [% Param('mailfrom') %]
-To: [% to %]
-Subject: [% flagtype_name %] [%+ subject_status %]: [[% terms.Bug %] [%+ bug.bug_id %]] [% bug.short_desc %]
-[%- IF attachment %] :
-  [Attachment [% attachment.id %]] [% attachment.description FILTER clean_text %][% END %]
-Date: [% date %]
-X-Bugzilla-Type: request
-[%+ INCLUDE "email/header-common.txt.tmpl" %]
-[%+ threadingmarker %]
 
 [%+ USE wrap -%]
 [%- FILTER bullet = wrap(80) -%]