Commit fc916610 authored by Max Kanat-Alexander's avatar Max Kanat-Alexander

Bug 545235: Simplify Bugzilla's language-choosing code

r=LpSolit, a=LpSolit
parent bb2b0198
...@@ -417,22 +417,7 @@ sub dbh_main { ...@@ -417,22 +417,7 @@ sub dbh_main {
sub languages { sub languages {
my $class = shift; my $class = shift;
return $class->request_cache->{languages} return Bugzilla::Install::Util::supported_languages();
if $class->request_cache->{languages};
my @files = glob(catdir(bz_locations->{'templatedir'}, '*'));
my @languages;
foreach my $dir_entry (@files) {
# It's a language directory only if it contains "default" or
# "custom". This auto-excludes CVS directories as well.
next unless (-d catdir($dir_entry, 'default')
|| -d catdir($dir_entry, 'custom'));
$dir_entry = basename($dir_entry);
# Check for language tag format conforming to RFC 1766.
next unless $dir_entry =~ /^[a-zA-Z]{1,8}(-[a-zA-Z]{1,8})?$/;
push(@languages, $dir_entry);
}
return $class->request_cache->{languages} = \@languages;
} }
sub error_mode { sub error_mode {
......
...@@ -279,84 +279,85 @@ sub install_string { ...@@ -279,84 +279,85 @@ sub install_string {
return $string_template; return $string_template;
} }
sub include_languages { sub _wanted_languages {
# If we are in CGI mode (not in checksetup.pl) and if the function has my ($requested, @wanted);
# been called without any parameter, then we cache the result of this
# function in Bugzilla->request_cache. This is done to improve the
# performance of the template processing.
my $to_be_cached = 0;
if (not @_) {
my $cache = _cache();
if (exists $cache->{include_languages}) {
return @{ $cache->{include_languages} };
}
$to_be_cached = 1;
}
my ($params) = @_;
$params ||= {};
# Basically, the way this works is that we have a list of languages # Checking SERVER_SOFTWARE is the same as i_am_cgi() in Bugzilla::Util.
# that we *want*, and a list of languages that Bugzilla actually
# supports. The caller tells us what languages they want, by setting
# $ENV{HTTP_ACCEPT_LANGUAGE}, using the "LANG" cookie or setting
# $params->{only_language}. The languages we support are those
# specified in $params->{use_languages}. Otherwise we support every
# language installed in the template/ directory.
my @wanted;
if ($params->{only_language}) {
@wanted = ($params->{only_language});
}
else {
@wanted = _sort_accept_language($ENV{'HTTP_ACCEPT_LANGUAGE'} || '');
# Don't use the cookie if we are in "checksetup.pl". The test
# with $ENV{'SERVER_SOFTWARE'} is the same as in
# Bugzilla:Util::i_am_cgi.
if (exists $ENV{'SERVER_SOFTWARE'}) { if (exists $ENV{'SERVER_SOFTWARE'}) {
my $cgi = Bugzilla->cgi; my $cgi = Bugzilla->cgi;
if (defined (my $lang = $cgi->cookie('LANG'))) { $requested = $cgi->http('Accept-Language') || '';
unshift @wanted, $lang; my $lang = $cgi->cookie('LANG');
} push(@wanted, $lang) if $lang;
}
}
my @supported;
if (defined $params->{use_languages}) {
@supported = @{$params->{use_languages}};
} }
else { else {
my @dirs = glob(bz_locations()->{'templatedir'} . "/*"); $requested = get_console_locale();
@dirs = map(basename($_), @dirs);
@supported = grep($_ ne 'CVS', @dirs);
} }
my @usedlanguages; push(@wanted, _sort_accept_language($requested));
foreach my $wanted (@wanted) { return \@wanted;
}
sub _wanted_to_actual_languages {
my ($wanted, $supported) = @_;
my @actual;
foreach my $lang (@$wanted) {
# If we support the language we want, or *any version* of # If we support the language we want, or *any version* of
# the language we want, it gets pushed into @usedlanguages. # the language we want, it gets pushed into @actual.
# #
# Per RFC 1766 and RFC 2616, things like 'en' match 'en-us' and # Per RFC 1766 and RFC 2616, things like 'en' match 'en-us' and
# 'en-uk', but not the other way around. (This is unfortunately # 'en-uk', but not the other way around. (This is unfortunately
# not very clearly stated in those RFC; see comment just over 14.5 # 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) # in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4)
if(my @found = grep /^\Q$wanted\E(-.+)?$/i, @supported) { my @found = grep(/^\Q$lang\E(-.+)?$/i, @$supported);
push (@usedlanguages, @found); push(@actual, @found) if @found;
}
} }
# We always include English at the bottom if it's not there, even if # We always include English at the bottom if it's not there, even if
# somebody removed it from use_languages. # it wasn't selected by the user.
if (!grep($_ eq 'en', @usedlanguages)) { if (!grep($_ eq 'en', @actual)) {
push(@usedlanguages, 'en'); push(@actual, 'en');
} }
# Cache the result if we are in CGI mode and called without parameter return \@actual;
# (see the comment at the top of this function). }
if ($to_be_cached) {
_cache()->{include_languages} = \@usedlanguages; sub supported_languages {
} my $cache = _cache();
return $cache->{supported_languages} if $cache->{supported_languages};
my @dirs = glob(bz_locations()->{'templatedir'} . "/*");
my @languages;
foreach my $dir (@dirs) {
# It's a language directory only if it contains "default" or
# "custom". This auto-excludes CVS directories as well.
next if (!-d "$dir/default" and !-d "$dir/custom");
my $lang = basename($dir);
# Check for language tag format conforming to RFC 1766.
next unless $lang =~ /^[a-zA-Z]{1,8}(-[a-zA-Z]{1,8})?$/;
push(@languages, $lang);
}
$cache->{supported_languages} = \@languages;
return \@languages;
}
return @usedlanguages; sub include_languages {
my ($params) = @_;
# Basically, the way this works is that we have a list of languages
# that we *want*, and a list of languages that Bugzilla actually
# supports.
my $wanted;
if ($params->{language}) {
$wanted = [$params->{language}];
}
else {
$wanted = _wanted_languages();
}
my $supported = supported_languages();
my $actual = _wanted_to_actual_languages($wanted, $supported);
return @$actual;
} }
# Used by template_include_path # Used by template_include_path
...@@ -550,7 +551,6 @@ sub get_console_locale { ...@@ -550,7 +551,6 @@ sub get_console_locale {
sub init_console { sub init_console {
eval { ON_WINDOWS && require Win32::Console::ANSI; }; eval { ON_WINDOWS && require Win32::Console::ANSI; };
$ENV{'ANSI_COLORS_DISABLED'} = 1 if ($@ || !-t *STDOUT); $ENV{'ANSI_COLORS_DISABLED'} = 1 if ($@ || !-t *STDOUT);
$ENV{'HTTP_ACCEPT_LANGUAGE'} ||= get_console_locale();
prevent_windows_dialog_boxes(); prevent_windows_dialog_boxes();
} }
......
...@@ -87,9 +87,8 @@ sub _load_constants { ...@@ -87,9 +87,8 @@ sub _load_constants {
sub getTemplateIncludePath { sub getTemplateIncludePath {
my $cache = Bugzilla->request_cache; my $cache = Bugzilla->request_cache;
my $lang = $cache->{'language'} || ''; my $lang = $cache->{'language'} || '';
$cache->{"template_include_path_$lang"} ||= template_include_path({ $cache->{"template_include_path_$lang"} ||=
use_languages => Bugzilla->languages, template_include_path({ language => $lang });
only_language => $lang });
return $cache->{"template_include_path_$lang"}; return $cache->{"template_include_path_$lang"};
} }
...@@ -815,7 +814,7 @@ sub precompile_templates { ...@@ -815,7 +814,7 @@ sub precompile_templates {
print install_string('template_precompile') if $output; print install_string('template_precompile') if $output;
my $paths = template_include_path({ use_languages => Bugzilla->languages }); my $paths = template_include_path();
foreach my $dir (@$paths) { foreach my $dir (@$paths) {
my $template = Bugzilla::Template->create(include_path => [$dir]); my $template = Bugzilla::Template->create(include_path => [$dir]);
......
...@@ -27,7 +27,7 @@ use strict; ...@@ -27,7 +27,7 @@ use strict;
use base qw(Template::Plugin); use base qw(Template::Plugin);
use Bugzilla::Constants; use Bugzilla::Constants;
use Bugzilla::Install::Util qw(include_languages template_include_path); use Bugzilla::Install::Util qw(template_include_path);
use Bugzilla::Util; use Bugzilla::Util;
use Bugzilla::Error; use Bugzilla::Error;
...@@ -97,8 +97,7 @@ sub _template_hook_include_path { ...@@ -97,8 +97,7 @@ sub _template_hook_include_path {
my $language = $cache->{language} || ''; my $language = $cache->{language} || '';
my $cache_key = "template_plugin_hook_include_path_$language"; my $cache_key = "template_plugin_hook_include_path_$language";
$cache->{$cache_key} ||= template_include_path({ $cache->{$cache_key} ||= template_include_path({
use_languages => Bugzilla->languages, language => $language,
only_language => $language,
hook => 1, hook => 1,
}); });
return $cache->{$cache_key}; return $cache->{$cache_key};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment