summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Morley <emorley@mozilla.com>2015-03-19 08:16:30 +0100
committerByron Jones <glob@mozilla.com>2015-03-19 08:16:30 +0100
commit6638a015487885a47bb0ba851865ef8b073d08fb (patch)
tree114070587bef8d7eb8dbc1f833258adbcd73dafd
parent2f65ef51e9ba430783a2d9ef06e0aa0af041d510 (diff)
downloadbugzilla-6638a015487885a47bb0ba851865ef8b073d08fb.tar.gz
bugzilla-6638a015487885a47bb0ba851865ef8b073d08fb.tar.xz
Bug 1105568: Add support for HTML flagmail
r=glob,a=glob
-rw-r--r--Bugzilla/BugMail.pm45
-rw-r--r--Bugzilla/Flag.pm27
-rw-r--r--Bugzilla/Mailer.pm64
-rw-r--r--Bugzilla/Product.pm1
-rw-r--r--template/en/default/email/flagmail-header.txt.tmpl28
-rw-r--r--template/en/default/email/flagmail.html.tmpl80
-rw-r--r--template/en/default/email/flagmail.txt.tmpl11
7 files changed, 187 insertions, 69 deletions
diff --git a/Bugzilla/BugMail.pm b/Bugzilla/BugMail.pm
index df39bd108..f655c4ae6 100644
--- a/Bugzilla/BugMail.pm
+++ b/Bugzilla/BugMail.pm
@@ -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 {
diff --git a/Bugzilla/Flag.pm b/Bugzilla/Flag.pm
index 50474b885..6d056e7e6 100644
--- a/Bugzilla/Flag.pm
+++ b/Bugzilla/Flag.pm
@@ -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));
}
}
diff --git a/Bugzilla/Mailer.pm b/Bugzilla/Mailer.pm
index ef75d0cf8..4f13f77d2 100644
--- a/Bugzilla/Mailer.pm
+++ b/Bugzilla/Mailer.pm
@@ -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.
diff --git a/Bugzilla/Product.pm b/Bugzilla/Product.pm
index 30ebc7c6c..0c0cb458d 100644
--- a/Bugzilla/Product.pm
+++ b/Bugzilla/Product.pm
@@ -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
index 000000000..8aa3955f7
--- /dev/null
+++ b/template/en/default/email/flagmail-header.txt.tmpl
@@ -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
index 000000000..314455c65
--- /dev/null
+++ b/template/en/default/email/flagmail.html.tmpl
@@ -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>
diff --git a/template/en/default/email/flagmail.txt.tmpl b/template/en/default/email/flagmail.txt.tmpl
index cf64d9661..9b80a493d 100644
--- a/template/en/default/email/flagmail.txt.tmpl
+++ b/template/en/default/email/flagmail.txt.tmpl
@@ -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 %]
@@ -31,17 +30,7 @@
[% 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) -%]