summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.htaccess32
-rw-r--r--Bugzilla/DB.pm13
-rw-r--r--Bugzilla/Install/Requirements.pm213
-rw-r--r--Bugzilla/Install/Util.pm27
-rw-r--r--Bugzilla/Template.pm22
-rw-r--r--js/bug.js4
-rw-r--r--js/comments.js11
-rw-r--r--template/en/default/admin/sudo.html.tmpl3
-rw-r--r--template/en/default/admin/users/userdata.html.tmpl5
-rw-r--r--template/en/default/bug/comments.html.tmpl13
-rw-r--r--template/en/default/bug/create/create.html.tmpl2
-rw-r--r--template/en/default/global/user-error.html.tmpl10
-rw-r--r--template/en/default/list/table.html.tmpl9
-rw-r--r--template/en/default/search/form.html.tmpl14
-rw-r--r--template/en/default/setup/strings.txt.pl17
15 files changed, 295 insertions, 100 deletions
diff --git a/.htaccess b/.htaccess
index d4436e563..4b06fe9a9 100644
--- a/.htaccess
+++ b/.htaccess
@@ -2,14 +2,24 @@
<FilesMatch ^(.*\.pm|.*\.pl|.*localconfig.*)$>
deny from all
</FilesMatch>
-<FilesMatch (\.js|\.css)$>
- ExpiresActive On
- # According to RFC 2616, "1 year in the future" means "never expire".
- # We change the name of the file's URL whenever its modification date
- # changes, so browsers can cache any individual JS or CSS URL forever.
- # However, since all JS and CSS URLs involve a ? in them (for the changing
- # name) we have to explicitly set an Expires header or browsers won't
- # *ever* cache them.
- ExpiresDefault "now plus 1 years"
- Header append Cache-Control "public"
-</FilesMatch>
+<IfModule mod_expires.c>
+<IfModule mod_headers.c>
+<IfModule mod_env.c>
+ <FilesMatch (\.js|\.css)$>
+ ExpiresActive On
+ # According to RFC 2616, "1 year in the future" means "never expire".
+ # We change the name of the file's URL whenever its modification date
+ # changes, so browsers can cache any individual JS or CSS URL forever.
+ # However, since all JS and CSS URLs involve a ? in them (for the changing
+ # name) we have to explicitly set an Expires header or browsers won't
+ # *ever* cache them.
+ ExpiresDefault "now plus 1 years"
+ Header append Cache-Control "public"
+ </FilesMatch>
+
+ # This lets Bugzilla know that we are properly sending Cache-Control
+ # and Expires headers for CSS and JS files.
+ SetEnv BZ_CACHE_CONTROL 1
+</IfModule>
+</IfModule>
+</IfModule>
diff --git a/Bugzilla/DB.pm b/Bugzilla/DB.pm
index 26e147f1f..6f1d3e6de 100644
--- a/Bugzilla/DB.pm
+++ b/Bugzilla/DB.pm
@@ -202,16 +202,19 @@ EOT
# And now check the version of the database server itself.
my $dbh = _get_no_db_connection();
- printf("Checking for %15s %-9s ", $sql_server, "(v$sql_want)")
- if $output;
my $sql_vers = $dbh->bz_server_version;
$dbh->disconnect;
+ my $version_ok = vers_cmp($sql_vers, $sql_want) > -1 ? 1 : 0;
+ if ($output) {
+ Bugzilla::Install::Requirements::_checking_for({
+ package => $sql_server, wanted => $sql_want,
+ found => $sql_vers, ok => $version_ok });
+ }
+
# Check what version of the database server is installed and let
# the user know if the version is too old to be used with Bugzilla.
- if ( vers_cmp($sql_vers,$sql_want) > -1 ) {
- print "ok: found v$sql_vers\n" if $output;
- } else {
+ if (!$version_ok) {
die <<EOT;
Your $sql_server v$sql_vers is too old. Bugzilla requires version
diff --git a/Bugzilla/Install/Requirements.pm b/Bugzilla/Install/Requirements.pm
index 5ed2d7dcd..5d2b6c39f 100644
--- a/Bugzilla/Install/Requirements.pm
+++ b/Bugzilla/Install/Requirements.pm
@@ -26,7 +26,7 @@ package Bugzilla::Install::Requirements;
use strict;
use Bugzilla::Constants;
-use Bugzilla::Install::Util qw(vers_cmp install_string
+use Bugzilla::Install::Util qw(vers_cmp install_string bin_loc
extension_requirement_packages);
use List::Util qw(max);
use Safe;
@@ -49,6 +49,34 @@ our @EXPORT = qw(
# by checksetup.pl.
use constant TABLE_WIDTH => 71;
+# Optional Apache modules that have no Perl component to them.
+# If these are installed, Bugzilla has additional functionality.
+#
+# The keys are the names of the modules, the values are what the module
+# is called in the output of "apachectl -t -D DUMP_MODULES".
+use constant APACHE_MODULES => {
+ mod_headers => 'headers_module',
+ mod_env => 'env_module',
+ mod_expires => 'expires_module',
+};
+
+# These are all of the binaries that we could possibly use that can
+# give us info about which Apache modules are installed.
+# If we can't use "apachectl", the "httpd" binary itself takes the same
+# parameters. Note that on Debian and Gentoo, there is an "apache2ctl",
+# but it takes different parameters on each of those two distros, so we
+# don't use apache2ctl.
+use constant APACHE => qw(apachectl httpd apache2 apache);
+
+# If we don't find any of the above binaries in the normal PATH,
+# these are extra places we look.
+use constant APACHE_PATH => [qw(
+ /usr/sbin
+ /usr/local/sbin
+ /usr/libexec
+ /usr/local/libexec
+)];
+
# The below two constants are subroutines so that they can implement
# a hook. Other than that they are actually constants.
@@ -347,6 +375,8 @@ sub check_requirements {
print "\n", install_string('checking_optional'), "\n" if $output;
my $missing_optional = _check_missing(OPTIONAL_MODULES, $output);
+ my $missing_apache = _missing_apache_modules(APACHE_MODULES, $output);
+
# If we're running on Windows, reset the input line terminator so that
# console input works properly - loading CGI tends to mess it up
$/ = "\015\012" if ON_WINDOWS;
@@ -357,6 +387,7 @@ sub check_requirements {
one_dbd => $have_one_dbd,
missing => $missing,
optional => $missing_optional,
+ apache => $missing_apache,
any_missing => !$pass || scalar(@$missing_optional),
};
}
@@ -375,6 +406,54 @@ sub _check_missing {
return \@missing;
}
+sub _missing_apache_modules {
+ my ($modules, $output) = @_;
+ my $apachectl = _get_apachectl();
+ return [] if !$apachectl;
+ my $command = "$apachectl -t -D DUMP_MODULES";
+ my $cmd_info = `$command 2>&1`;
+ # If apachectl returned a value greater than 0, then there was an
+ # error parsing Apache's configuration, and we can't check modules.
+ my $retval = $?;
+ if ($retval > 0) {
+ print STDERR install_string('apachectl_failed',
+ { command => $command, root => ROOT_USER }), "\n";
+ return [];
+ }
+ my @missing;
+ foreach my $module (keys %$modules) {
+ my $ok = _check_apache_module($module, $modules->{$module},
+ $cmd_info, $output);
+ push(@missing, $module) if !$ok;
+ }
+ return \@missing;
+}
+
+sub _get_apachectl {
+ foreach my $bin_name (APACHE) {
+ my $bin = bin_loc($bin_name);
+ return $bin if $bin;
+ }
+ # Try again with a possibly different path.
+ foreach my $bin_name (APACHE) {
+ my $bin = bin_loc($bin_name, APACHE_PATH);
+ return $bin if $bin;
+ }
+ return undef;
+}
+
+sub _check_apache_module {
+ my ($module, $config_name, $mod_info, $output) = @_;
+ my $ok;
+ if ($mod_info =~ /^\s+\Q$config_name\E\b/m) {
+ $ok = 1;
+ }
+ if ($output) {
+ _checking_for({ package => $module, ok => $ok });
+ }
+ return $ok;
+}
+
sub print_module_instructions {
my ($check_results, $output) = @_;
@@ -411,30 +490,41 @@ sub print_module_instructions {
}
}
+ if (my @missing = @{ $check_results->{apache} }) {
+ print install_string('modules_message_apache');
+ my $missing_string = join(', ', @missing);
+ my $size = TABLE_WIDTH - 7;
+ printf "* \%-${size}s *\n", $missing_string;
+ my $spaces = TABLE_WIDTH - 2;
+ print "*", (' ' x $spaces), "*\n";
+ }
+
+ my $need_module_instructions =
+ ( (!$output and @{$check_results->{missing}})
+ or ($output and $check_results->{any_missing}) ) ? 1 : 0;
+
# We only print the PPM repository note if we have to.
- if ((!$output && @{$check_results->{missing}})
- || ($output && $check_results->{any_missing}))
- {
- if (ON_ACTIVESTATE) {
- my $perl_ver = sprintf('%vd', $^V);
+ if ($need_module_instructions and ON_ACTIVESTATE) {
+ my $perl_ver = sprintf('%vd', $^V);
- # URL when running Perl 5.8.x.
- my $url_to_theory58S = 'http://theoryx5.uwinnipeg.ca/ppms';
- # Packages for Perl 5.10 are not compatible with Perl 5.8.
- if (vers_cmp($perl_ver, '5.10') > -1) {
- $url_to_theory58S = 'http://cpan.uwinnipeg.ca/PPMPackages/10xx/';
- }
- print colored(
- install_string('ppm_repo_add',
- { theory_url => $url_to_theory58S }),
- COLOR_ERROR);
-
- # ActivePerls older than revision 819 require an additional command.
- if (ON_ACTIVESTATE < 819) {
- print install_string('ppm_repo_up');
- }
+ # URL when running Perl 5.8.x.
+ my $url_to_theory58S = 'http://theoryx5.uwinnipeg.ca/ppms';
+ # Packages for Perl 5.10 are not compatible with Perl 5.8.
+ if (vers_cmp($perl_ver, '5.10') > -1) {
+ $url_to_theory58S = 'http://cpan.uwinnipeg.ca/PPMPackages/10xx/';
}
+ print colored(
+ install_string('ppm_repo_add',
+ { theory_url => $url_to_theory58S }),
+ COLOR_ERROR);
+
+ # ActivePerls older than revision 819 require an additional command.
+ if (ON_ACTIVESTATE < 819) {
+ print install_string('ppm_repo_up');
+ }
+ }
+ if ($need_module_instructions or @{ $check_results->{apache} }) {
# If any output was required, we want to close the "table"
print "*" x TABLE_WIDTH . "\n";
}
@@ -494,15 +584,14 @@ sub check_graphviz {
my $webdotbase = Bugzilla->params->{'webdotbase'};
return 1 if $webdotbase =~ /^https?:/;
- my $checking_for = install_string('checking_for');
- my $any = install_string('any');
- printf("%s %15s %-9s ", $checking_for, "GraphViz", "($any)") if $output;
+ my $return;
+ $return = 1 if -x $webdotbase;
+
+ if ($output) {
+ _checking_for({ package => 'GraphViz', ok => $return });
+ }
- my $return = 0;
- if(-x $webdotbase) {
- print install_string('module_ok'), "\n" if $output;
- $return = 1;
- } else {
+ if (!$return) {
print install_string('bad_executable', { bin => $webdotbase }), "\n";
}
@@ -554,17 +643,6 @@ sub have_vers {
$vnum = $1;
}
- my $vstr;
- if ($vnum eq "-1") { # string compare just in case it's non-numeric
- $vstr = install_string('module_not_found');
- }
- elsif (vers_cmp($vnum,"0") > -1) {
- $vstr = install_string('module_found', { ver => $vnum });
- }
- else {
- $vstr = install_string('module_unknown_version');
- }
-
my $vok = (vers_cmp($vnum,$wanted) > -1);
my $blacklisted;
if ($vok && $params->{blacklist}) {
@@ -573,19 +651,52 @@ sub have_vers {
}
if ($output) {
- my $ok = $vok ? install_string('module_ok') : '';
- my $black_string = $blacklisted ? install_string('blacklisted') : '';
- my $want_string = $wanted ? "v$wanted" : install_string('any');
-
- $ok = "$ok:" if $ok;
- my $str = sprintf "%s %19s %-9s $ok $vstr $black_string\n",
- install_string('checking_for'), $package, "($want_string)";
- print $vok ? $str : colored($str, COLOR_ERROR);
+ _checking_for({
+ package => $package, ok => $vok, wanted => $wanted,
+ found => $vnum, blacklisted => $blacklisted
+ });
}
return $vok ? 1 : 0;
}
+sub _checking_for {
+ my ($params) = @_;
+ my ($package, $ok, $wanted, $blacklisted, $found) =
+ @$params{qw(package ok wanted blacklisted found)};
+
+ my $ok_string = $ok ? install_string('module_ok') : '';
+
+ # If we're actually checking versions (like for Perl modules), then
+ # we have some rather complex logic to determine what we want to
+ # show. If we're not checking versions (like for GraphViz) we just
+ # show "ok" or "not found".
+ if (exists $params->{found}) {
+ my $found_string;
+ # We do a string compare in case it's non-numeric.
+ if ($found and $found eq "-1") {
+ $found_string = install_string('module_not_found');
+ }
+ elsif ($found) {
+ $found_string = install_string('module_found', { ver => $found });
+ }
+ else {
+ $found_string = install_string('module_unknown_version');
+ }
+ $ok_string = $ok ? "$ok_string: $found_string" : $found_string;
+ }
+ elsif (!$ok) {
+ $ok_string = install_string('module_not_found');
+ }
+
+ my $black_string = $blacklisted ? install_string('blacklisted') : '';
+ my $want_string = $wanted ? "v$wanted" : install_string('any');
+
+ my $str = sprintf "%s %20s %-11s $ok_string $black_string\n",
+ install_string('checking_for'), $package, "($want_string)";
+ print $ok ? $str : colored($str, COLOR_ERROR);
+}
+
sub install_command {
my $module = shift;
my ($command, $package);
@@ -707,10 +818,12 @@ a hashref in the format of items from L</REQUIRED_MODULES>.
=item C<optional> - The same as C<missing>, but for optional modules.
+=item C<apache> - The name of each optional Apache module that is missing.
+
=item C<have_one_dbd> - True if at least one C<DBD::> module is installed.
-=item C<any_missing> - True if there are any missing modules, even optional
-modules.
+=item C<any_missing> - True if there are any missing Perl modules, even
+optional modules.
=back
diff --git a/Bugzilla/Install/Util.pm b/Bugzilla/Install/Util.pm
index d65d2f592..50cbfd2a8 100644
--- a/Bugzilla/Install/Util.pm
+++ b/Bugzilla/Install/Util.pm
@@ -29,7 +29,9 @@ use strict;
use Bugzilla::Constants;
use Encode;
+use ExtUtils::MM ();
use File::Basename;
+use File::Spec;
use POSIX qw(setlocale LC_CTYPE);
use Safe;
use Scalar::Util qw(tainted);
@@ -54,18 +56,19 @@ our @EXPORT_OK = qw(
);
sub bin_loc {
- my ($bin) = @_;
- return '' if ON_WINDOWS;
- # Don't print any errors from "which"
- open(my $saveerr, ">&STDERR");
- open(STDERR, '>/dev/null');
- my $loc = `which $bin`;
- close(STDERR);
- open(STDERR, ">&", $saveerr);
- my $exit_code = $? >> 8; # See the perlvar manpage.
- return '' if $exit_code > 0;
- chomp($loc);
- return $loc;
+ my ($bin, $path) = @_;
+ my @path = $path ? @$path : File::Spec->path;
+
+ foreach my $dir (@path) {
+ next if !-d $dir;
+ my $full_path = File::Spec->catfile($dir, $bin);
+ # MM is an alias for ExtUtils::MM. maybe_command is nice
+ # because it checks .com, .bat, .exe (etc.) on Windows.
+ my $command = MM->maybe_command($full_path);
+ return $command if $command;
+ }
+
+ return '';
}
sub get_version_and_os {
diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm
index 13ba22776..0997415b2 100644
--- a/Bugzilla/Template.pm
+++ b/Bugzilla/Template.pm
@@ -399,10 +399,17 @@ sub multiline_sprintf {
sub _mtime { return (stat($_[0]))[9] }
sub mtime_filter {
- my ($file_url) = @_;
- my $cgi_path = bz_locations()->{'cgi_path'};
- my $file_path = "$cgi_path/$file_url";
- return "$file_url?" . _mtime($file_path);
+ my ($file_url, $mtime) = @_;
+ # This environment var is set in the .htaccess if we have mod_headers
+ # and mod_expires installed, to make sure that JS and CSS with "?"
+ # after them will still be cached by clients.
+ return $file_url if !$ENV{BZ_CACHE_CONTROL};
+ if (!$mtime) {
+ my $cgi_path = bz_locations()->{'cgi_path'};
+ my $file_path = "$cgi_path/$file_url";
+ $mtime = _mtime($file_path);
+ }
+ return "$file_url?$mtime";
}
# Set up the skin CSS cascade:
@@ -453,8 +460,7 @@ sub css_files {
sub _css_link_set {
my ($file_name) = @_;
- my $standard_mtime = _mtime($file_name);
- my %set = (standard => $file_name . "?$standard_mtime");
+ my %set = (standard => mtime_filter($file_name));
# We use (^|/) to allow Extensions to use the skins system if they
# want.
@@ -471,7 +477,7 @@ sub _css_link_set {
my $skin_file_name = $file_name;
$skin_file_name =~ s{(^|/)skins/standard/}{skins/contrib/$option/};
if (my $mtime = _mtime("$cgi_path/$skin_file_name")) {
- $skin_urls{$option} = $skin_file_name . "?$mtime";
+ $skin_urls{$option} = mtime_filter($skin_file_name, $mtime);
}
}
$set{alternate} = \%skin_urls;
@@ -484,7 +490,7 @@ sub _css_link_set {
my $custom_file_name = $file_name;
$custom_file_name =~ s{(^|/)skins/standard/}{skins/custom/};
if (my $custom_mtime = _mtime("$cgi_path/$custom_file_name")) {
- $set{custom} = $custom_file_name . "?$custom_mtime";
+ $set{custom} = mtime_filter($custom_file_name, $custom_mtime);
}
return \%set;
diff --git a/js/bug.js b/js/bug.js
index baea5125f..ca888a68f 100644
--- a/js/bug.js
+++ b/js/bug.js
@@ -100,7 +100,7 @@ YAHOO.bugzilla.dupTable = {
new_ds.maxCacheEntries = 3;
new_ds.responseSchema = {
resultsList : "result.bugs",
- metaFields : { error: "error", jsonRpcId: "id" },
+ metaFields : { error: "error", jsonRpcId: "id" }
};
// DataSource can't understand a JSON-RPC error response, so
// we have to modify the result data if we get one.
@@ -125,5 +125,5 @@ YAHOO.bugzilla.dupTable = {
this.dataSource, data.options);
YAHOO.util.Event.on(data.summary_field, 'keyup', this.doUpdateTable,
[dt, data.product_name]);
- },
+ }
};
diff --git a/js/comments.js b/js/comments.js
index 79bdae855..697cedd20 100644
--- a/js/comments.js
+++ b/js/comments.js
@@ -86,3 +86,14 @@ function addCollapseLink(count) {
'); return false;" title="Collapse the comment.">[-]<\/a> ');
}
+function goto_add_comments( anchor ){
+ anchor = (anchor || "add_comment");
+ // we need this line to expand the comment box
+ document.getElementById('comment').focus();
+ setTimeout(function(){
+ document.location.hash = anchor;
+ // firefox doesn't seem to keep focus through the anchor change
+ document.getElementById('comment').focus();
+ },10);
+ return false;
+}
diff --git a/template/en/default/admin/sudo.html.tmpl b/template/en/default/admin/sudo.html.tmpl
index 680bcfbb3..283eebe15 100644
--- a/template/en/default/admin/sudo.html.tmpl
+++ b/template/en/default/admin/sudo.html.tmpl
@@ -83,8 +83,7 @@
password</label>:
<input type="hidden" name="Bugzilla_login" value="
[%- user.login FILTER html %]">
- <input type="password" id="Bugzilla_password" name="Bugzilla_password"
- maxlength="20" size="20">
+ <input type="password" id="Bugzilla_password" name="Bugzilla_password" size="20">
<br>
This is done for two reasons. First of all, it is done to reduce
the chances of someone doing large amounts of damage using your
diff --git a/template/en/default/admin/users/userdata.html.tmpl b/template/en/default/admin/users/userdata.html.tmpl
index d81529b48..5df1f7c8c 100644
--- a/template/en/default/admin/users/userdata.html.tmpl
+++ b/template/en/default/admin/users/userdata.html.tmpl
@@ -61,9 +61,8 @@
<tr>
<th><label for="password">Password:</label></th>
<td>
- <input type="password" size="16" maxlength="16" name="password"
- autocomplete="off"
- id="password" value="" />
+ <input type="password" size="16" name="password" id="password"
+ value="" autocomplete="off" />
[% IF editform %]<br />
(Enter new password to change.)
[% END %]
diff --git a/template/en/default/bug/comments.html.tmpl b/template/en/default/bug/comments.html.tmpl
index e44e4e7b9..9a7a050af 100644
--- a/template/en/default/bug/comments.html.tmpl
+++ b/template/en/default/bug/comments.html.tmpl
@@ -65,6 +65,14 @@
[% count = count + increment %]
[% END %]
+[% IF user.settings.comment_box_position.value == "before_comments" && user.id %]
+ <div class="bz_add_comment">
+ <a href="#"
+ onclick="return goto_add_comments();">
+ Add Comment</a>
+ </div>
+[% END %]
+
[%# Note: this template is used in multiple places; if you use this hook,
# make sure you are aware of this fact.
#%]
@@ -78,6 +86,11 @@
return false;">Collapse All Comments</a></li>
<li><a href="#" onclick="toggle_all_comments('expand', [% comments.size %]);
return false;">Expand All Comments</a></li>
+ [% IF user.settings.comment_box_position.value == "after_comments" && user.id %]
+ <li class="bz_add_comment"><a href="#"
+ onclick="return goto_add_comments('bug_status_bottom');">
+ Add Comment</a></li>
+ [% END %]
</ul>
[% END %]
</td>
diff --git a/template/en/default/bug/create/create.html.tmpl b/template/en/default/bug/create/create.html.tmpl
index ebb222850..43f113150 100644
--- a/template/en/default/bug/create/create.html.tmpl
+++ b/template/en/default/bug/create/create.html.tmpl
@@ -550,7 +550,7 @@ TUI_hide_default('attachment_text_field');
MSG_LOADING: 'Searching for possible duplicates...',
MSG_EMPTY: 'No possible duplicates found.',
SUMMARY: 'Possible Duplicates'
- },
+ }
});
</script>
</td>
diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl
index 2d5ad72d7..a885f4b34 100644
--- a/template/en/default/global/user-error.html.tmpl
+++ b/template/en/default/global/user-error.html.tmpl
@@ -246,8 +246,14 @@
[% IF reason == 'http' %]
URLs must start with "http" or "https".
[% ELSIF reason == 'show_bug' %]
- [%+ terms.Bug %] URLs should point to <code>show_bug.cgi</code>
- in a [% terms.Bugzilla %] installation.
+ [%+ field_descs.see_also %] URLs should point to one of:
+ <ul>
+ <li><code>show_bug.cgi</code> in a [% terms.Bugzilla %]
+ installation.</li>
+ <li>A b[% %]ug on launchpad.net</li>
+ <li>An issue on code.google.com.</li>
+ <li>A b[% %]ug on b[% %]ugs.debian.org.</li>
+ </ul>
[% ELSIF reason == 'id' %]
There is no valid [% terms.bug %] id in that URL.
[% END %]
diff --git a/template/en/default/list/table.html.tmpl b/template/en/default/list/table.html.tmpl
index 789d4c42e..3fb687415 100644
--- a/template/en/default/list/table.html.tmpl
+++ b/template/en/default/list/table.html.tmpl
@@ -72,6 +72,8 @@
[% PROCESS bug/time.html.tmpl %]
+[% Hook.process("before_table") %]
+
[%############################################################################%]
[%# Table Header #%]
[%############################################################################%]
@@ -163,8 +165,6 @@
[%# Bug Table #%]
[%############################################################################%]
-[% Hook.process("before_table") %]
-
[% tableheader %]
[% FOREACH bug = bugs %]
@@ -207,7 +207,10 @@
[% SET login_column = column.remove('_realname$') %]
[% bug.${login_column}.truncate(abbrev.$column.maxlength,
abbrev.$column.ellipsis) FILTER html %]
-
+ [% ELSIF column == 'short_desc' || column == "short_short_desc" %]
+ <a href="show_bug.cgi?id=[% bug.id FILTER html %]">
+ [%- bug.$column.truncate(abbrev.$column.maxlength, abbrev.$column.ellipsis) FILTER html -%]
+ </a>
[% ELSE %]
[%- display_value(column, bug.$column).truncate(abbrev.$column.maxlength, abbrev.$column.ellipsis) FILTER html -%]
[% END %]
diff --git a/template/en/default/search/form.html.tmpl b/template/en/default/search/form.html.tmpl
index e1f8a5f68..f519c8f69 100644
--- a/template/en/default/search/form.html.tmpl
+++ b/template/en/default/search/form.html.tmpl
@@ -342,7 +342,19 @@ TUI_hide_default('information_query');
[% " selected" IF default.emailtype.$n == qv.name %]>[% qv.description %]</option>
[% END %]
</select>
- <input name="email[% n %]" class="email" id="email[% n %]" value="[% default.email.$n FILTER html %]">
+ [% IF feature_enabled('jsonrpc') %]
+ <div id="email[% n %]_autocomplete">
+ [% END %]
+ <input name="email[% n %]" class="email" id="email[% n %]"
+ value="[% default.email.$n FILTER html %]">
+ [% IF feature_enabled('jsonrpc') %]
+ <div id="email[% n %]_autocomplete_container"></div>
+ </div>
+ <script type="text/javascript">
+ YAHOO.bugzilla.userAutocomplete.init( "email[% n %]",
+ "email[% n %]_autocomplete_container");
+ </script>
+ [% END %]
</div>
[% END %]
[% Hook.process('email_numbering_end') %]
diff --git a/template/en/default/setup/strings.txt.pl b/template/en/default/setup/strings.txt.pl
index 350c701aa..f03869205 100644
--- a/template/en/default/setup/strings.txt.pl
+++ b/template/en/default/setup/strings.txt.pl
@@ -28,6 +28,11 @@
%strings = (
any => 'any',
+ apachectl_failed => <<END,
+WARNING: We could not check the configuration of Apache. This sometimes
+happens when you are not running checksetup.pl as ##root##. To see the
+problem we ran into, run: ##command##
+END
bad_executable => 'not a valid executable: ##bin##',
blacklisted => '(blacklisted)',
bz_schema_exists_before_220 => <<'END',
@@ -260,6 +265,18 @@ EOT
# Note: When translating these "modules" messages, don't change the formatting
# if possible, because there is hardcoded formatting in
# Bugzilla::Install::Requirements to match the box formatting.
+ modules_message_apache => <<END,
+***********************************************************************
+* APACHE MODULES *
+***********************************************************************
+* Normally, when Bugzilla is upgraded, all Bugzilla users have to *
+* clear their browser cache or Bugzilla will break. If you enable *
+* certain modules in your Apache configuration (usually called *
+* httpd.conf or apache2.conf) then your users will not have to clear *
+* their caches when you upgrade Bugzilla. The modules you need to *
+* enable are: *
+* *
+END
modules_message_db => <<EOT,
***********************************************************************
* DATABASE ACCESS *