diff options
-rw-r--r-- | Bugzilla.pm | 14 | ||||
-rwxr-xr-x | Bugzilla/Bug.pm | 46 | ||||
-rw-r--r-- | Bugzilla/BugMail.pm | 56 | ||||
-rw-r--r-- | Bugzilla/Install.pm | 8 | ||||
-rw-r--r-- | Bugzilla/Template.pm | 16 | ||||
-rw-r--r-- | Bugzilla/User/Setting.pm | 21 | ||||
-rwxr-xr-x | editparams.cgi | 14 | ||||
-rw-r--r-- | template/en/default/global/setting-descs.none.tmpl | 1 |
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", } %] |