summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Bugzilla/BugMail.pm60
-rw-r--r--Bugzilla/Template.pm6
-rw-r--r--template/en/default/email/bugmail-common.txt.html38
-rw-r--r--template/en/default/email/bugmail-header.txt.tmpl47
-rw-r--r--template/en/default/email/bugmail.html.tmpl126
-rw-r--r--template/en/default/email/bugmail.txt.tmpl (renamed from template/en/default/email/newchangedmail.txt.tmpl)52
6 files changed, 268 insertions, 61 deletions
diff --git a/Bugzilla/BugMail.pm b/Bugzilla/BugMail.pm
index 2ac575293..dfd7584ea 100644
--- a/Bugzilla/BugMail.pm
+++ b/Bugzilla/BugMail.pm
@@ -29,6 +29,7 @@
# Byron Jones <bugzilla@glob.com.au>
# Reed Loden <reed@reedloden.com>
# Frédéric Buclin <LpSolit@gmail.com>
+# Guy Pyrzak <guy.pyrzak@gmail.com>
use strict;
@@ -83,10 +84,9 @@ sub Send {
# can 'have' a role, if the person in that role has changed, or people are
# watching.
my @assignees = ($bug->assigned_to);
- my @qa_contacts = ($bug->qa_contact);
+ my @qa_contacts = $bug->qa_contact || ();
my @ccs = @{ $bug->cc_users };
-
# Include the people passed in as being in particular roles.
# This can include people who used to hold those roles.
# At this point, we don't care if there are duplicates in these arrays.
@@ -104,6 +104,7 @@ sub Send {
push(@ccs, Bugzilla::User->check($cc));
}
}
+ my %user_cache = map { $_->id => $_ } (@assignees, @qa_contacts, @ccs);
my @diffs;
if (!$start) {
@@ -123,7 +124,7 @@ sub Send {
blocker => $params->{blocker} });
}
else {
- push(@diffs, _get_diffs($bug, $end));
+ push(@diffs, _get_diffs($bug, $end, \%user_cache));
}
my $comments = $bug->comments({ after => $start, to => $end });
@@ -220,7 +221,8 @@ sub Send {
foreach my $user_id (keys %recipients) {
my %rels_which_want;
my $sent_mail = 0;
- my $user = new Bugzilla::User($user_id);
+ $user_cache{$user_id} ||= new Bugzilla::User($user_id);
+ my $user = $user_cache{$user_id};
# Deleted users must be excluded.
next unless $user;
@@ -353,19 +355,47 @@ sub sendMail {
new_comments => \@send_comments,
threadingmarker => build_thread_marker($bug->id, $user->id, !$bug->lastdiffed),
};
-
- my $msg;
- my $template = Bugzilla->template_inner($user->settings->{'lang'}->{'value'});
- $template->process("email/newchangedmail.txt.tmpl", $vars, \$msg)
- || ThrowTemplateError($template->error());
-
+ my $msg = _generate_bugmail($user, $vars);
MessageToMTA($msg);
return 1;
}
+sub _generate_bugmail {
+ my ($user, $vars) = @_;
+ my $template = Bugzilla->template_inner($user->settings->{'lang'}->{'value'});
+ 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());
+ $template->process("email/bugmail.html.tmpl", $vars, \$msg_html)
+ || ThrowTemplateError($template->error());
+
+ my @parts = (
+ Email::MIME->create(
+ attributes => {
+ content_type => "text/plain",
+ },
+ body => $msg_text,
+ ),
+ Email::MIME->create(
+ attributes => {
+ content_type => "text/html",
+ },
+ body => $msg_html,
+ ),
+ );
+
+ my $email = new Email::MIME($msg_header);
+ $email->parts_set(\@parts);
+ $email->content_type_set('multipart/alternative');
+ return $email;
+}
+
sub _get_diffs {
- my ($bug, $end) = @_;
+ my ($bug, $end, $user_cache) = @_;
my $dbh = Bugzilla->dbh;
my @args = ($bug->id);
@@ -377,20 +407,20 @@ sub _get_diffs {
}
my $diffs = $dbh->selectall_arrayref(
- "SELECT profiles.login_name, profiles.realname, fielddefs.name AS field_name,
+ "SELECT fielddefs.name AS field_name,
bugs_activity.bug_when, bugs_activity.removed AS old,
bugs_activity.added AS new, bugs_activity.attach_id,
- bugs_activity.comment_id
+ bugs_activity.comment_id, bugs_activity.who
FROM bugs_activity
INNER JOIN fielddefs
ON fielddefs.id = bugs_activity.fieldid
- INNER JOIN profiles
- ON profiles.userid = bugs_activity.who
WHERE bugs_activity.bug_id = ?
$when_restriction
ORDER BY bugs_activity.bug_when", {Slice=>{}}, @args);
foreach my $diff (@$diffs) {
+ $user_cache->{$diff->{who}} ||= new Bugzilla::User($diff->{who});
+ $diff->{who} = $user_cache->{$diff->{who}};
if ($diff->{attach_id}) {
$diff->{isprivate} = $dbh->selectrow_array(
'SELECT isprivate FROM attachments WHERE attach_id = ?',
diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm
index 5ff5482b2..ee4d6cba2 100644
--- a/Bugzilla/Template.pm
+++ b/Bugzilla/Template.pm
@@ -348,8 +348,12 @@ sub get_bug_link {
}
# Prevent code injection in the title.
$title = html_quote(clean_text($title));
-
my $linkval = "show_bug.cgi?id=" . $bug->id;
+
+ if ($options->{full_url}) {
+ $linkval = correct_urlbase() . $linkval;
+ }
+
if (defined $options->{comment_num}) {
$linkval .= "#c" . $options->{comment_num};
}
diff --git a/template/en/default/email/bugmail-common.txt.html b/template/en/default/email/bugmail-common.txt.html
new file mode 100644
index 000000000..b6cadaf11
--- /dev/null
+++ b/template/en/default/email/bugmail-common.txt.html
@@ -0,0 +1,38 @@
+[%# The contents of this file are subject to the Mozilla Public
+ # License Version 1.1 (the "License"); you may not use this file
+ # except in compliance with the License. You may obtain a copy of
+ # the License at http://www.mozilla.org/MPL/
+ #
+ # Software distributed under the License is distributed on an "AS
+ # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ # implied. See the License for the specific language governing
+ # rights and limitations under the License.
+ #
+ # The Original Code is the Bugzilla Bug Tracking System.
+ #
+ # The Initial Developer of the Original Code is Guy Pyrzak
+ # Portions created by the Initial Developer are Copyright (C) 2010 the
+ # Initial Developer. All Rights Reserved.
+ #
+ # Contributor(s): Guy Pyrzak <guy.pyrzak@gmail.com>
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+
+[% field_label = field_descs.${change.field_name} %]
+[% old_value = display_value(change.field_name, change.old) %]
+[% new_value = display_value(change.field_name, change.new) %]
+
+[% IF change.field_name == "estimated_time" || change.field_name == "remaining_time" %]
+ [% old_value = old_value FILTER format('%.2f') %]
+ [% new_value = new_value FILTER format('%.2f') %]
+[% END %]
+
+[% IF change.attach_id %]
+ [% field_label = field_label.replace('^(Attachment )?', "Attachment #${change.attach_id} ") %]
+[% END %]
+
+[% IF change.field_name == 'longdescs.isprivate' %]
+ [% field_label = field_label.replace('^(Comment )?', "Comment #${change.num} ") %]
+[% END %]
+ \ No newline at end of file
diff --git a/template/en/default/email/bugmail-header.txt.tmpl b/template/en/default/email/bugmail-header.txt.tmpl
new file mode 100644
index 000000000..c2b4ea4f5
--- /dev/null
+++ b/template/en/default/email/bugmail-header.txt.tmpl
@@ -0,0 +1,47 @@
+[%# The contents of this file are subject to the Mozilla Public
+ # License Version 1.1 (the "License"); you may not use this file
+ # except in compliance with the License. You may obtain a copy of
+ # the License at http://www.mozilla.org/MPL/
+ #
+ # Software distributed under the License is distributed on an "AS
+ # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ # implied. See the License for the specific language governing
+ # rights and limitations under the License.
+ #
+ # The Original Code is the Bugzilla Bug Tracking System.
+ #
+ # The Initial Developer of the Original Code is Netscape Communications
+ # Corporation. Portions created by Netscape are
+ # Copyright (C) 1998 Netscape Communications Corporation. All
+ # Rights Reserved.
+ #
+ # Contributor(s): André Batosti <batosti@async.com.br>
+ # Frédéric Buclin <LpSolit@gmail.com>
+ # Guy Pyrzak <guy.pyrzak@gmail.com>
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+[% PROCESS "global/reason-descs.none.tmpl" %]
+[% isnew = bug.lastdiffed ? 0 : 1 %]
+
+From: [% Param('mailfrom') %]
+To: [% to_user.email %]
+Subject: [[% terms.Bug %] [%+ bug.id %]] [% 'New: ' IF isnew %][%+ bug.short_desc %]
+Date: [% delta_ts || bug.delta_ts FILTER time("%a, %d %b %Y %T %z", to_user.timezone) %]
+X-Bugzilla-Reason: [% reasonsheader %]
+X-Bugzilla-Type: [% isnew ? 'new' : 'changed' %]
+X-Bugzilla-Watch-Reason: [% reasonswatchheader %]
+[% IF Param('useclassification') %]
+X-Bugzilla-Classification: [% bug.classification %]
+[% END %]
+X-Bugzilla-Product: [% bug.product %]
+X-Bugzilla-Component: [% bug.component %]
+X-Bugzilla-Keywords: [% bug.keywords %]
+X-Bugzilla-Severity: [% bug.bug_severity %]
+X-Bugzilla-Who: [% changer.login %]
+X-Bugzilla-Status: [% bug.bug_status %]
+X-Bugzilla-Priority: [% bug.priority %]
+X-Bugzilla-Assigned-To: [% bug.assigned_to.login %]
+X-Bugzilla-Target-Milestone: [% bug.target_milestone %]
+X-Bugzilla-Changed-Fields: [% changedfields.join(" ") %]
+[%+ threadingmarker %]
diff --git a/template/en/default/email/bugmail.html.tmpl b/template/en/default/email/bugmail.html.tmpl
new file mode 100644
index 000000000..888d47bc4
--- /dev/null
+++ b/template/en/default/email/bugmail.html.tmpl
@@ -0,0 +1,126 @@
+[%# The contents of this file are subject to the Mozilla Public
+ # License Version 1.1 (the "License"); you may not use this file
+ # except in compliance with the License. You may obtain a copy of
+ # the License at http://www.mozilla.org/MPL/
+ #
+ # Software distributed under the License is distributed on an "AS
+ # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ # implied. See the License for the specific language governing
+ # rights and limitations under the License.
+ #
+ # The Original Code is the Bugzilla Bug Tracking System.
+ #
+ # The Initial Developer of the Original Code is Guy Pyrzak
+ # Portions created by the Initial Developer are Copyright (C) 2010 the
+ # Initial Developer. All Rights Reserved.
+ #
+ # Contributor(s): Guy Pyrzak <guy.pyrzak@gmail.com>
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+[% PROCESS "global/reason-descs.none.tmpl" %]
+
+[% isnew = bug.lastdiffed ? 0 : 1 %]
+<html>
+ <head>
+ <base href="[% %]" />
+ </head>
+ <body>
+ [% PROCESS generate_diffs %]
+ <p>
+ [% FOREACH comment = new_comments.reverse %]
+ <div>
+ [% IF comment.count %]
+ <b>[% "Comment # ${comment.count}" FILTER bug_link( bug,
+ {comment_num => comment.count, full_url => 1}) FILTER none %]
+ from [% INCLUDE global/user.html.tmpl who = comment.author %]</b>
+ [% END %]
+ <pre>[% comment.body_full({ wrap => 1 }) FILTER html %]</pre>
+ </div>
+ [% END %]
+ </p>
+ <p>
+ <a href="[% urlbase FILTER html %]userprefs.cgi?tab=email">
+ Configure [% terms.bug %]mail
+ </a>
+ </p>
+
+ <span>You are receiving this mail because:</span>
+
+ <ul>
+ [% FOREACH reason = reasons %]
+ [% IF reason_descs.$reason %]
+ <li>[% reason_descs.$reason FILTER html %]</li>
+ [% END %]
+ [% END %]
+ [% FOREACH reason = reasons_watch %]
+ [% IF watch_reason_descs.$reason %]
+ <li>[% watch_reason_descs.$reason FILTER html %]</li>
+ [% END %]
+ [% END %]
+ </ul>
+ </body>
+</html>
+
+[% BLOCK generate_diffs %]
+
+ [% "${terms.Bug} ${bug.id}" FILTER bug_link(bug, full_url => 1) FILTER none %]
+
+ [% last_changer = "" %]
+ <table border="1" cellspacing="0" cellpadding="2">
+ [% FOREACH change = diffs %]
+ [% IF !isnew && change.who.login != last_changer %]
+ [% last_changer = change.who.login %]
+ [% IF change.blocker %]
+ <tr>
+ <td colspan="3">
+ [% "${terms.Bug} ${bug.id}" FILTER bug_link(bug, full_url => 1) FILTER none %] depends
+ on [% "${terms.bug} ${change.blocker.id}"
+ FILTER bug_link(change.blocker, full_url => 1) FILTER none %],
+ which changed state.
+ </td>
+ </tr>
+ [% ELSE %]
+ <tr>
+ <td colspan="3">
+ [% INCLUDE global/user.html.tmpl who = change.who %]
+ changed:
+ </td>
+ </tr>
+ [% END %]
+ <tr>
+ <th>What</th>
+ <th>Removed</th>
+ <th>Added</th>
+ </tr>
+ [% END %]
+
+ [% PROCESS "email/bugmail-common.txt.html" %]
+
+ [% IF isnew %]
+ <tr>
+ <th>[% field_label FILTER html %]</th>
+ <td>[% new_value FILTER html %]</td>
+ </tr>
+ [% ELSE %]
+ <tr>
+ <td style="text-align:right;">[% field_label FILTER html %]</td>
+ <td>
+ [% IF old_value %]
+ [% old_value FILTER html %]
+ [% ELSE %]
+ &nbsp;
+ [% END%]
+ </td>
+ <td>
+ [% IF new_value %]
+ [% new_value FILTER html %]
+ [% ELSE %]
+ &nbsp;
+ [% END%]
+ </td>
+ </tr>
+ [% END %]
+ [% END %]
+ </table>
+[% END %] \ No newline at end of file
diff --git a/template/en/default/email/newchangedmail.txt.tmpl b/template/en/default/email/bugmail.txt.tmpl
index de4a248e3..31efaba33 100644
--- a/template/en/default/email/newchangedmail.txt.tmpl
+++ b/template/en/default/email/bugmail.txt.tmpl
@@ -17,6 +17,7 @@
#
# Contributor(s): André Batosti <batosti@async.com.br>
# Frédéric Buclin <LpSolit@gmail.com>
+ # Guy Pyrzak <guy.pyrzak@gmail.com>
#%]
[% PROCESS "global/field-descs.none.tmpl" %]
@@ -24,28 +25,6 @@
[% isnew = bug.lastdiffed ? 0 : 1 %]
-From: [% Param('mailfrom') %]
-To: [% to_user.email %]
-Subject: [[% terms.Bug %] [%+ bug.id %]] [% 'New: ' IF isnew %][%+ bug.short_desc %]
-Date: [% delta_ts || bug.delta_ts FILTER time("%a, %d %b %Y %T %z", to_user.timezone) %]
-X-Bugzilla-Reason: [% reasonsheader %]
-X-Bugzilla-Type: [% isnew ? 'new' : 'changed' %]
-X-Bugzilla-Watch-Reason: [% reasonswatchheader %]
-[% IF Param('useclassification') %]
-X-Bugzilla-Classification: [% bug.classification %]
-[% END %]
-X-Bugzilla-Product: [% bug.product %]
-X-Bugzilla-Component: [% bug.component %]
-X-Bugzilla-Keywords: [% bug.keywords %]
-X-Bugzilla-Severity: [% bug.bug_severity %]
-X-Bugzilla-Who: [% changer.login %]
-X-Bugzilla-Status: [% bug.bug_status %]
-X-Bugzilla-Priority: [% bug.priority %]
-X-Bugzilla-Assigned-To: [% bug.assigned_to.login %]
-X-Bugzilla-Target-Milestone: [% bug.target_milestone %]
-X-Bugzilla-Changed-Fields: [% changedfields.join(" ") %]
-[%+ threadingmarker %]
-
[%+ PROCESS generate_diffs -%]
[% FOREACH comment = new_comments %]
@@ -74,42 +53,25 @@ Configure [% terms.bug %]mail: [% urlbase %]userprefs.cgi?tab=email
[%+ last_changer = "" %]
[% FOREACH change = diffs %]
- [% IF !isnew && change.login_name != last_changer %]
- [% last_changer = change.login_name %]
+ [% IF !isnew && change.who.login != last_changer %]
+ [% last_changer = change.who.login %]
[% IF change.blocker %]
[% terms.Bug %] [%+ bug.id %] depends on [% terms.bug %] [%+ change.blocker.id %], which changed state.
[%+ terms.Bug %] [%+ change.blocker.id %] Summary: [% change.blocker.short_desc %]
[%+ urlbase %]show_bug.cgi?id=[% change.blocker.id %]
[% ELSE %]
- [%~ IF change.realname %]
- [% change.realname _ " <" _ change.login_name _ ">" %]
+ [%~ IF change.who.name %]
+ [% change.who.name _ " <" _ change.who.login _ ">" %]
[% ELSE %]
- [% change.login_name %]
+ [% change.who.login %]
[% END %] changed:
[% END %]
What |Removed |Added
----------------------------------------------------------------------------
[%+ END %][%# End of IF. This indentation is intentional! ~%]
-
- [% field_label = field_descs.${change.field_name} %]
- [% old_value = display_value(change.field_name, change.old) %]
- [% new_value = display_value(change.field_name, change.new) %]
-
- [%~ IF change.field_name == "estimated_time" || change.field_name == "remaining_time" %]
- [% old_value = old_value FILTER format('%.2f') %]
- [% new_value = new_value FILTER format('%.2f') %]
- [% END %]
-
- [%~ IF change.attach_id %]
- [% field_label = field_label.replace('^(Attachment )?', "Attachment #${change.attach_id} ") %]
- [% END %]
-
- [%~ IF change.field_name == 'longdescs.isprivate' %]
- [% field_label = field_label.replace('^(Comment )?', "Comment #${change.num} ") %]
- [% END %]
-
+ [% PROCESS "email/bugmail-common.txt.html"%]
[%~ IF isnew %]
[% format_columns(2, field_label _ ":", new_value) -%]
[% ELSE %]