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:
parent
d258207ff6
commit
aeeefad863
@ -1 +1 @@
|
|||||||
9340
|
9341
|
||||||
@ -1 +1 @@
|
|||||||
2f65ef51e9ba430783a2d9ef06e0aa0af041d510
|
6638a015487885a47bb0ba851865ef8b073d08fb
|
||||||
@ -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 {
|
||||||
|
|||||||
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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 %]
|
||||||
@ -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>
|
||||||
@ -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) -%]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user