use Bugzilla::CGI;
use Bugzilla::DB;
use Bugzilla::Install::Localconfig qw(read_localconfig);
+use Bugzilla::Install::Requirements qw(OPTIONAL_MODULES);
use Bugzilla::JobQueue;
use Bugzilla::Template;
use Bugzilla::User;
return $class->request_cache->{"template_inner_$lang"};
}
+sub feature {
+ my ($class, $feature) = @_;
+ my $cache = $class->request_cache;
+ return $cache->{feature}->{$feature}
+ if exists $cache->{feature}->{$feature};
+
+ my $feature_map = $cache->{feature_map};
+ if (!$feature_map) {
+ foreach my $package (@{ OPTIONAL_MODULES() }) {
+ foreach my $f (@{ $package->{feature} }) {
+ $feature_map->{$f} ||= [];
+ push(@{ $feature_map->{$f} }, $package->{module});
+ }
+ }
+ $cache->{feature_map} = $feature_map;
+ }
+
+ if (!$feature_map->{$feature}) {
+ ThrowCodeError('invalid_feature', { feature => $feature });
+ }
+
+ my $success = 1;
+ foreach my $module (@{ $feature_map->{$feature} }) {
+ # We can't use a string eval and "use" here (it kills Template-Toolkit,
+ # see https://rt.cpan.org/Public/Bug/Display.html?id=47929), so we have
+ # to do a block eval.
+ $module =~ s{::}{/}g;
+ $module .= ".pm";
+ eval { require $module; 1; } or $success = 0;
+ }
+ $cache->{feature}->{$feature} = $success;
+ return $success;
+}
+
sub cgi {
my $class = shift;
$class->request_cache->{cgi} ||= new Bugzilla::CGI();
Will throw an error if job queueing is not correctly configured on
this Bugzilla installation.
+=item C<feature>
+
+Tells you whether or not a specific feature is enabled. For names
+of features, see C<OPTIONAL_MODULES> in C<Bugzilla::Install::Requirements>.
+
=back
# If the attachment is a patch, try to link to the diff rather
# than the text, by default.
my $patchlink = "";
- if ($is_patch) {
- # Determine if PatchReader is installed
- my $patchviewer_installed = eval { require PatchReader; };
- if ($patchviewer_installed) {
- $patchlink = '&action=diff';
- }
+ if ($is_patch and Bugzilla->feature('patch_viewer')) {
+ $patchlink = '&action=diff';
}
# Whitespace matters here because these links are in <pre> tags.
return \@bug_list;
},
+ 'feature_enabled' => sub { return Bugzilla->feature(@_); },
+
# These don't work as normal constants.
DB_MODULE => \&Bugzilla::Constants::DB_MODULE,
REQUIRED_MODULES =>
Bugzilla->login();
}
-# Determine if PatchReader is installed
-eval {
- require PatchReader;
- $vars->{'patchviewerinstalled'} = 1;
-};
-
# When viewing an attachment, do not request credentials if we are on
# the alternate host. Let view() decide when to call Bugzilla->login.
if ($action eq "view")
else {
$vars->{'message'} = 'attachment_creation_failed';
}
-
- # Determine if Patch Viewer is installed, for Diff link
- eval {
- require PatchReader;
- $vars->{'patchviewerinstalled'} = 1;
- };
}
# Set bug flags.
}
}
-# Determine if Patch Viewer is installed, for Diff link
-# (NB: Duplicate code with show_bug.cgi.)
-eval {
- require PatchReader;
- $vars->{'patchviewerinstalled'} = 1;
-};
-
if (Bugzilla->usage_mode == USAGE_MODE_EMAIL) {
# Do nothing.
}
}
}
-# Determine if Patch Viewer is installed, for Diff link
-eval {
- require PatchReader;
- $vars->{'patchviewerinstalled'} = 1;
-};
-
$vars->{'bugs'} = \@bugs;
$vars->{'marks'} = \%marks;
%]
[%# No need to display the Diff button and iframe if the attachment is not a patch. %]
-[% patchviewerinstalled = (patchviewerinstalled && attachment.ispatch) %]
+[% use_patchviewer = (feature_enabled('patch_viewer') && attachment.ispatch) %]
<form method="post" action="attachment.cgi" onsubmit="normalizeComments();">
<input type="hidden" name="id" value="[% attachment.id %]">
<input type="submit" value="Submit" id="update"><br><br>
<strong>Actions:</strong>
<a href="attachment.cgi?id=[% attachment.id %]">View</a>
- [% IF attachment.ispatch && patchviewerinstalled %]
+ [% IF use_patchviewer %]
| <a href="attachment.cgi?id=[% attachment.id %]&action=diff">Diff</a>
[% END %]
[% IF Param("allow_attachment_deletion")
var patchviewerinstalled = 0;
var attachment_id = [% attachment.id %];
if (typeof document.getElementById == "function") {
-[% IF patchviewerinstalled %]
+[% IF use_patchviewer %]
var patchviewerinstalled = 1;
document.write('<iframe id="viewDiffFrame" style="height: 400px; width: 100%; display: none;"><\/iframe>');
[% END %]
document.write('<button type="button" id="editButton" onclick="editAsComment(patchviewerinstalled);">Edit Attachment As Comment<\/button>');
document.write('<button type="button" id="undoEditButton" onclick="undoEditAsComment(patchviewerinstalled);" style="display: none;">Undo Edit As Comment<\/button>');
document.write('<button type="button" id="redoEditButton" onclick="redoEditAsComment(patchviewerinstalled);" style="display: none;">Redo Edit As Comment<\/button>');
-[% IF patchviewerinstalled %]
+[% IF use_patchviewer %]
document.write('<button type="button" id="viewDiffButton" onclick="viewDiff(attachment_id, patchviewerinstalled);">View Attachment As Diff<\/button>');
[% END %]
document.write('<button type="button" id="viewRawButton" onclick="viewRaw(patchviewerinstalled);" style="display: none;">View Attachment As Raw<\/button>');
<td valign="top">
<a href="attachment.cgi?id=[% attachment.id %]&action=edit">Details</a>
- [% IF attachment.ispatch && patchviewerinstalled %]
+ [% IF attachment.ispatch && feature_enabled('patch_viewer') %]
| <a href="attachment.cgi?id=[% attachment.id %]&action=diff">Diff</a>
[% END %]
[% Hook.process("action") %]
[% title = "Invalid Dimensions" %]
The width or height specified is not a positive integer.
+ [% ELSIF error == "invalid_feature" %]
+ [% title = "Invalid Feature Name" %]
+ [% feature FILTER html %] is not a valid feature name. See
+ <code>OPTIONAL_MODULES</code> in
+ <code>Bugzilla::Install::Requirements</code> for valid names.
+
[% ELSIF error == "invalid_flag_association" %]
[% title = "Invalid Flag Association" %]
Some flags do not belong to