Bug 1105568: Add support for HTML flagmail

r=glob,a=glob


git-svn-id: svn://10.0.0.236/trunk@265885 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bzrmirror%bugzilla.org 2015-03-19 07:30:50 +00:00
parent d258207ff6
commit aeeefad863
9 changed files with 189 additions and 71 deletions

View File

@ -1 +1 @@
9340 9341

View File

@ -1 +1 @@
2f65ef51e9ba430783a2d9ef06e0aa0af041d510 6638a015487885a47bb0ba851865ef8b073d08fb

View File

@ -437,45 +437,12 @@ sub _flatten_object {
sub _generate_bugmail { sub _generate_bugmail {
my ($vars) = @_; my ($vars) = @_;
my $user = $vars->{to_user}; my $templates = {
my $template = Bugzilla->template_inner($user->setting('lang')); header => "email/bugmail-header.txt.tmpl",
my ($msg_text, $msg_html, $msg_header); text => "email/bugmail.txt.tmpl",
html => "email/bugmail.html.tmpl",
$template->process("email/bugmail-header.txt.tmpl", $vars, \$msg_header) };
|| ThrowTemplateError($template->error()); return generate_email($vars, $templates);
$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;
} }
sub _get_diffs { sub _get_diffs {

View File

@ -1116,13 +1116,6 @@ sub notify {
if ($addressee && $addressee->email_enabled) { if ($addressee && $addressee->email_enabled) {
$recipients{$addressee->email} = $addressee; $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 # Get comments on the bug
my $all_comments = $bug->comments({ after => $bug->lastdiffed }); my $all_comments = $bug->comments({ after => $bug->lastdiffed });
@ -1132,18 +1125,20 @@ sub notify {
my $public_comments = [ grep { !$_->is_private } @$all_comments ]; my $public_comments = [ grep { !$_->is_private } @$all_comments ];
foreach my $to (keys %recipients) { foreach my $to (keys %recipients) {
my $user = $recipients{$to};
# Add threadingmarker to allow flag notification emails to be the # Add threadingmarker to allow flag notification emails to be the
# threaded similar to normal bug change emails. # 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 # 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; ? $all_comments : $public_comments;
my $vars = { my $vars = {
flag => $flag, flag => $flag,
old_flag => $old_flag, old_flag => $old_flag,
to => $to, to => $to,
to_user => $user,
date => $timestamp, date => $timestamp,
bug => $bug, bug => $bug,
attachment => $attachment, attachment => $attachment,
@ -1151,15 +1146,13 @@ sub notify {
new_comments => $comments, new_comments => $comments,
}; };
my $lang = $recipients{$to} ? my $templates = {
$recipients{$to}->setting('lang') : $default_lang; header => "email/flagmail-header.txt.tmpl",
text => "email/flagmail.txt.tmpl",
html => "email/flagmail.html.tmpl",
};
my $template = Bugzilla->template_inner($lang); MessageToMTA(generate_email($vars, $templates));
my $message;
$template->process("email/flagmail.txt.tmpl", $vars, \$message)
|| ThrowTemplateError($template->error());
MessageToMTA($message);
} }
} }

View File

@ -12,11 +12,12 @@ use strict;
use warnings; use warnings;
use parent qw(Exporter); 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::Constants;
use Bugzilla::Error; use Bugzilla::Error;
use Bugzilla::Hook; use Bugzilla::Hook;
use Bugzilla::User;
use Bugzilla::Util; use Bugzilla::Util;
use Date::Format qw(time2str); use Date::Format qw(time2str);
@ -28,6 +29,63 @@ use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP::Persistent; use Email::Sender::Transport::SMTP::Persistent;
use Bugzilla::Sender::Transport::Sendmail; 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 { sub MessageToMTA {
my ($msg, $send_now) = (@_); my ($msg, $send_now) = (@_);
my $method = Bugzilla->params->{'mail_delivery_method'}; my $method = Bugzilla->params->{'mail_delivery_method'};
@ -285,6 +343,10 @@ Bugzilla::Mailer - Provides methods for sending email
=over =over
=item C<generate_email>
Generates a multi-part email message, using the supplied list of templates.
=item C<MessageToMTA> =item C<MessageToMTA>
Sends the passed message to the mail transfer agent. Sends the passed message to the mail transfer agent.

View File

@ -22,7 +22,6 @@ use Bugzilla::Milestone;
use Bugzilla::Field; use Bugzilla::Field;
use Bugzilla::Status; use Bugzilla::Status;
use Bugzilla::Install::Requirements; use Bugzilla::Install::Requirements;
use Bugzilla::Mailer;
use Bugzilla::Series; use Bugzilla::Series;
use Bugzilla::Hook; use Bugzilla::Hook;
use Bugzilla::FlagType; use Bugzilla::FlagType;

View File

@ -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 %]

View File

@ -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>

View File

@ -17,7 +17,6 @@
[% action = flag.status || 'X' %] [% action = flag.status || 'X' %]
[% IF flag && flag.status == '?' %] [% IF flag && flag.status == '?' %]
[% subject_status = "requested" %]
[% IF flag.setter_id == user.id %] [% IF flag.setter_id == user.id %]
[% to_identity = flag.requestee.identity _ " for" %] [% to_identity = flag.requestee.identity _ " for" %]
[% ELSE %] [% ELSE %]
@ -31,17 +30,7 @@
[% requestee_identity = old_flag.requestee.identity _ "'s" %] [% requestee_identity = old_flag.requestee.identity _ "'s" %]
[% END %] [% END %]
[% END %] [% END %]
[% subject_status = statuses.$action %]
[% END %] [% 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 -%] [%+ USE wrap -%]
[%- FILTER bullet = wrap(80) -%] [%- FILTER bullet = wrap(80) -%]