aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Bugzilla.pm14
-rwxr-xr-xBugzilla/Bug.pm46
-rw-r--r--Bugzilla/BugMail.pm56
-rw-r--r--Bugzilla/Install.pm8
-rw-r--r--Bugzilla/Template.pm16
-rw-r--r--Bugzilla/User/Setting.pm21
-rwxr-xr-xeditparams.cgi14
-rw-r--r--template/en/default/global/setting-descs.none.tmpl1
8 files changed, 128 insertions, 48 deletions
diff --git a/Bugzilla.pm b/Bugzilla.pm
index 32f731859..f278adb2e 100644
--- a/Bugzilla.pm
+++ b/Bugzilla.pm
@@ -146,14 +146,17 @@ init_page() if !$ENV{MOD_PERL};
sub template {
my $class = shift;
+ request_cache()->{language} = "";
request_cache()->{template} ||= Bugzilla::Template->create();
return request_cache()->{template};
}
sub template_inner {
- my $class = shift;
- $class->request_cache->{template_inner} ||= Bugzilla::Template->create();
- return $class->request_cache->{template_inner};
+ my ($class, $lang) = @_;
+ $lang = defined($lang) ? $lang : (request_cache()->{language} || "");
+ request_cache()->{language} = $lang;
+ request_cache()->{"template_inner_$lang"} ||= Bugzilla::Template->create();
+ return request_cache()->{"template_inner_$lang"};
}
sub cgi {
@@ -497,7 +500,10 @@ The current C<Template> object, to be used for output
=item C<template_inner>
If you ever need a L<Bugzilla::Template> object while you're already
-processing a template, use this.
+processing a template, use this. Also use it if you want to specify
+the language to use. If no argument is passed, it uses the last
+language set. If the argument is "" (empty string), the language is
+reset to the current one (the one used by Bugzilla->template).
=item C<cgi>
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm
index f09386a0c..469b6ff60 100755
--- a/Bugzilla/Bug.pm
+++ b/Bugzilla/Bug.pm
@@ -1405,7 +1405,7 @@ sub ValidateTime {
}
sub GetComments {
- my ($id, $comment_sort_order, $start, $end) = @_;
+ my ($id, $comment_sort_order, $start, $end, $raw) = @_;
my $dbh = Bugzilla->dbh;
$comment_sort_order = $comment_sort_order ||
@@ -1438,21 +1438,9 @@ sub GetComments {
$comment{'email'} .= Bugzilla->params->{'emailsuffix'};
$comment{'name'} = $comment{'name'} || $comment{'email'};
- if ($comment{'type'} == CMT_DUPE_OF) {
- $comment{'body'} .= "\n\n" . get_text('bug_duplicate_of',
- { dupe_of => $comment{'extra_data'} });
- }
- elsif ($comment{'type'} == CMT_HAS_DUPE) {
- $comment{'body'} = get_text('bug_has_duplicate',
- { dupe => $comment{'extra_data'} });
- }
- elsif ($comment{'type'} == CMT_POPULAR_VOTES) {
- $comment{'body'} = get_text('bug_confirmed_by_votes');
- }
- elsif ($comment{'type'} == CMT_MOVED_TO) {
- $comment{'body'} .= "\n\n" . get_text('bug_moved_to',
- { login => $comment{'extra_data'} });
- }
+
+ # If raw data is requested, do not format 'special' comments.
+ $comment{'body'} = format_comment(\%comment) unless $raw;
push (@comments, \%comment);
}
@@ -1464,6 +1452,32 @@ sub GetComments {
return \@comments;
}
+# Format language specific comments. This routine must not update
+# $comment{'body'} itself, see BugMail::prepare_comments().
+sub format_comment {
+ my $comment = shift;
+ my $body;
+
+ if ($comment->{'type'} == CMT_DUPE_OF) {
+ $body = $comment->{'body'} . "\n\n" .
+ get_text('bug_duplicate_of', { dupe_of => $comment->{'extra_data'} });
+ }
+ elsif ($comment->{'type'} == CMT_HAS_DUPE) {
+ $body = get_text('bug_has_duplicate', { dupe => $comment->{'extra_data'} });
+ }
+ elsif ($comment->{'type'} == CMT_POPULAR_VOTES) {
+ $body = get_text('bug_confirmed_by_votes');
+ }
+ elsif ($comment->{'type'} == CMT_MOVED_TO) {
+ $body = $comment->{'body'} . "\n\n" .
+ get_text('bug_moved_to', { login => $comment->{'extra_data'} });
+ }
+ else {
+ $body = $comment->{'body'};
+ }
+ return $body;
+}
+
# Get the activity of a bug, starting from $starttime (if given).
# This routine assumes ValidateBugID has been previously called.
sub GetBugActivity {
diff --git a/Bugzilla/BugMail.pm b/Bugzilla/BugMail.pm
index 6ba6b3c77..6e0f57401 100644
--- a/Bugzilla/BugMail.pm
+++ b/Bugzilla/BugMail.pm
@@ -313,7 +313,7 @@ sub Send {
}
- my ($newcomments, $anyprivate) = get_comments_by_bug($id, $start, $end);
+ my ($raw_comments, $anyprivate, $count) = get_comments_by_bug($id, $start, $end);
###########################################################################
# Start of email filtering code
@@ -408,6 +408,9 @@ sub Send {
my @sent;
my @excluded;
+ # Some comments are language specific. We cache them here.
+ my %comments;
+
foreach my $user_id (keys %recipients) {
my %rels_which_want;
my $sent_mail = 0;
@@ -416,15 +419,24 @@ sub Send {
# Deleted users must be excluded.
next unless $user;
- if ($user->can_see_bug($id))
- {
+ # What's the language chosen by this user for email?
+ my $lang = $user->settings->{'lang'}->{'value'};
+
+ if ($user->can_see_bug($id)) {
+ # It's time to format language specific comments.
+ unless (exists $comments{$lang}) {
+ Bugzilla->template_inner($lang);
+ $comments{$lang} = prepare_comments($raw_comments, $count);
+ Bugzilla->template_inner("");
+ }
+
# Go through each role the user has and see if they want mail in
# that role.
foreach my $relationship (keys %{$recipients{$user_id}}) {
if ($user->wants_bug_mail($id,
$relationship,
$diffs,
- $newcomments,
+ $comments{$lang},
$changer,
!$start))
{
@@ -471,7 +483,7 @@ sub Send {
\%defmailhead,
\%fielddescription,
\@diffparts,
- $newcomments,
+ $comments{$lang},
$anyprivate,
$start,
$id,
@@ -634,16 +646,17 @@ sub sendMail {
};
my $msg;
- my $template = Bugzilla->template_inner;
+ my $template = Bugzilla->template_inner($user->settings->{'lang'}->{'value'});
$template->process("email/newchangedmail.txt.tmpl", $vars, \$msg)
|| ThrowTemplateError($template->error());
+ Bugzilla->template_inner("");
MessageToMTA($msg);
return 1;
}
-# Get bug comments for the given period and format them to be used in emails.
+# Get bug comments for the given period.
sub get_comments_by_bug {
my ($id, $start, $end) = @_;
my $dbh = Bugzilla->dbh;
@@ -661,22 +674,35 @@ sub get_comments_by_bug {
undef, ($id, $start));
}
- my $comments = Bugzilla::Bug::GetComments($id, "oldest_to_newest", $start, $end);
+ my $raw = 1; # Do not format comments which are not of type CMT_NORMAL.
+ my $comments = Bugzilla::Bug::GetComments($id, "oldest_to_newest", $start, $end, $raw);
+
+ if (Bugzilla->params->{'insidergroup'}) {
+ $anyprivate = 1 if scalar(grep {$_->{'isprivate'} > 0} @$comments);
+ }
+
+ return ($comments, $anyprivate, $count);
+}
+
+# Prepare comments for the given language.
+sub prepare_comments {
+ my ($raw_comments, $count) = @_;
- foreach my $comment (@$comments) {
+ my $result = "";
+ foreach my $comment (@$raw_comments) {
if ($count) {
$result .= "\n\n--- Comment #$count from " . $comment->{'name'} . " <" .
$comment->{'email'} . Bugzilla->params->{'emailsuffix'} . "> " .
format_time($comment->{'time'}) . " ---\n";
}
- if ($comment->{'isprivate'} > 0 && Bugzilla->params->{'insidergroup'}) {
- $anyprivate = 1;
- }
- $result .= ($comment->{'already_wrapped'} ? $comment->{'body'}
- : wrap_comment($comment->{'body'}));
+ # Format language specific comments. We don't update $comment->{'body'}
+ # directly, otherwise it would grow everytime you call format_comment()
+ # with a different language as some text may be appended to the existing one.
+ my $body = Bugzilla::Bug::format_comment($comment);
+ $result .= ($comment->{'already_wrapped'} ? $body : wrap_comment($body));
$count++;
}
- return ($result, $anyprivate);
+ return $result;
}
1;
diff --git a/Bugzilla/Install.pm b/Bugzilla/Install.pm
index c31bb58df..218ee6359 100644
--- a/Bugzilla/Install.pm
+++ b/Bugzilla/Install.pm
@@ -35,7 +35,8 @@ use Bugzilla::User::Setting;
use Bugzilla::Util qw(get_text);
use Bugzilla::Version;
-use constant SETTINGS => {
+sub SETTINGS {
+ return {
# 2005-03-03 travis@sedsystems.ca -- Bug 41972
display_quips => { options => ["on", "off"], default => "on" },
# 2005-03-10 travis@sedsystems.ca -- Bug 199048
@@ -56,7 +57,10 @@ use constant SETTINGS => {
default => 'cc_unless_role' },
# 2006-08-04 wurblzap@gmail.com -- Bug 322693
skin => { subclass => 'Skin', default => 'standard' },
-
+ # 2006-12-10 LpSolit@gmail.com -- Bug 297186
+ lang => { options => [split(/[\s,]+/, Bugzilla->params->{'languages'})],
+ default => Bugzilla->params->{'defaultlanguage'} }
+ }
};
use constant SYSTEM_GROUPS => (
diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm
index ed6880b01..608d35fcb 100644
--- a/Bugzilla/Template.pm
+++ b/Bugzilla/Template.pm
@@ -108,9 +108,10 @@ sub sortAcceptLanguage {
# If no Accept-Language is present it uses the defined default
# Templates may also be found in the extensions/ tree
sub getTemplateIncludePath {
+ my $lang = Bugzilla->request_cache->{'language'} || "";
# Return cached value if available
- my $include_path = Bugzilla->request_cache->{template_include_path};
+ my $include_path = Bugzilla->request_cache->{"template_include_path_$lang"};
return $include_path if $include_path;
my $templatedir = bz_locations()->{'templatedir'};
@@ -132,15 +133,16 @@ sub getTemplateIncludePath {
}
}
my @languages = sortAcceptLanguage($languages);
- my @accept_language = sortAcceptLanguage($ENV{'HTTP_ACCEPT_LANGUAGE'} || "" );
+ # If $lang is specified, only consider this language.
+ my @accept_language = ($lang) || sortAcceptLanguage($ENV{'HTTP_ACCEPT_LANGUAGE'} || "");
my @usedlanguages;
- foreach my $lang (@accept_language) {
+ foreach my $language (@accept_language) {
# Per RFC 1766 and RFC 2616 any language tag matches also its
# primary tag. That is 'en' (accept language) matches 'en-us',
# 'en-uk' etc. but not the otherway round. (This is unfortunately
# not very clearly stated in those RFC; see comment just over 14.5
# in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4)
- if(my @found = grep /^\Q$lang\E(-.+)?$/i, @languages) {
+ if(my @found = grep /^\Q$language\E(-.+)?$/i, @languages) {
push (@usedlanguages, @found);
}
}
@@ -180,9 +182,9 @@ sub getTemplateIncludePath {
foreach my $dir (@$include_path) {
push(@dirs, $dir) unless grep ($dir eq $_, @dirs);
}
- Bugzilla->request_cache->{template_include_path} = \@dirs;
+ Bugzilla->request_cache->{"template_include_path_$lang"} = \@dirs;
- return Bugzilla->request_cache->{template_include_path};
+ return Bugzilla->request_cache->{"template_include_path_$lang"};
}
sub put_header {
@@ -527,7 +529,7 @@ sub create {
# We need a possibility to reset the cache, so that no files from
# the previous language pollute the action.
if ($opts{'clean_cache'}) {
- delete Bugzilla->request_cache->{template_include_path};
+ delete Bugzilla->request_cache->{template_include_path_};
}
# IMPORTANT - If you make any configuration changes here, make sure to
diff --git a/Bugzilla/User/Setting.pm b/Bugzilla/User/Setting.pm
index ad39d194b..bdc653b97 100644
--- a/Bugzilla/User/Setting.pm
+++ b/Bugzilla/User/Setting.pm
@@ -15,7 +15,7 @@
# Contributor(s): Shane H. W. Travis <travis@sedsystems.ca>
# Max Kanat-Alexander <mkanat@bugzilla.org>
# Marc Schumann <wurblzap@gmail.com>
-#
+# Frédéric Buclin <LpSolit@gmail.com>
package Bugzilla::User::Setting;
@@ -128,15 +128,28 @@ sub new {
###############################
sub add_setting {
- my ($name, $values, $default_value, $subclass) = @_;
+ my ($name, $values, $default_value, $subclass, $force_check) = @_;
my $dbh = Bugzilla->dbh;
- return if _setting_exists($name);
+ my $exists = _setting_exists($name);
+ return if ($exists && !$force_check);
($name && $default_value)
|| ThrowCodeError("setting_info_invalid");
- print get_text('install_setting_new', { name => $name }) . "\n";
+ if ($exists) {
+ # If this setting exists, we delete it and regenerate it.
+ $dbh->do('DELETE FROM setting_value WHERE name = ?', undef, $name);
+ $dbh->do('DELETE FROM setting WHERE name = ?', undef, $name);
+ # Remove obsolete user preferences for this setting.
+ my $list = join(', ', map {$dbh->quote($_)} @$values);
+ $dbh->do("DELETE FROM profile_setting
+ WHERE setting_name = ? AND setting_value NOT IN ($list)",
+ undef, $name);
+ }
+ else {
+ print get_text('install_setting_new', { name => $name }) . "\n";
+ }
$dbh->do(q{INSERT INTO setting (name, default_value, is_enabled, subclass)
VALUES (?, ?, 1, ?)},
undef, ($name, $default_value, $subclass));
diff --git a/editparams.cgi b/editparams.cgi
index 80b458d90..ca74df685 100755
--- a/editparams.cgi
+++ b/editparams.cgi
@@ -33,6 +33,7 @@ use Bugzilla::Util;
use Bugzilla::Error;
use Bugzilla::Token;
use Bugzilla::User;
+use Bugzilla::User::Setting;
my $user = Bugzilla->login(LOGIN_REQUIRED);
my $cgi = Bugzilla->cgi;
@@ -73,6 +74,7 @@ if ($action eq 'save' && $current_module) {
my @changes = ();
my @module_param_list = "Bugzilla::Config::${current_module}"->get_param_list(1);
+ my $update_lang_user_pref = 0;
foreach my $i (@module_param_list) {
my $name = $i->{'name'};
my $value = $cgi->param($name);
@@ -132,8 +134,20 @@ if ($action eq 'save' && $current_module) {
if (($name eq "shutdownhtml") && ($value ne "")) {
$vars->{'shutdown_is_active'} = 1;
}
+ if ($name eq 'languages') {
+ $update_lang_user_pref = 1;
+ }
}
}
+ if ($update_lang_user_pref) {
+ # We have to update the list of languages users can choose.
+ # If some users have selected a language which is no longer available,
+ # then we delete it (the user pref is reset to the default one).
+ my @languages = split(/[\s,]+/, Bugzilla->params->{'languages'});
+ map {trick_taint($_)} @languages;
+ add_setting('lang', \@languages, Bugzilla->params->{'defaultlanguage'}, undef, 1);
+ }
+
$vars->{'message'} = 'parameters_updated';
$vars->{'param_changed'} = \@changes;
diff --git a/template/en/default/global/setting-descs.none.tmpl b/template/en/default/global/setting-descs.none.tmpl
index 4fb2a031b..e62ec0b63 100644
--- a/template/en/default/global/setting-descs.none.tmpl
+++ b/template/en/default/global/setting-descs.none.tmpl
@@ -40,5 +40,6 @@
"always" => "Always",
"never" => "Never",
"cc_unless_role" => "Only if I have no role on them",
+ "lang" => "Language used in email",
}
%]