Hook.pm 3.66 KB
Newer Older
1 2 3
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
#
5 6
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.
7 8

package Bugzilla::Template::Plugin::Hook;
9 10

use 5.10.1;
11
use strict;
12
use warnings;
13

14
use parent qw(Template::Plugin);
15

16
use Bugzilla::Constants;
17
use Bugzilla::Install::Util qw(template_include_path); 
18 19 20
use Bugzilla::Util;
use Bugzilla::Error;

21
use File::Spec;
22 23 24 25 26 27

sub new {
    my ($class, $context) = @_;
    return bless { _CONTEXT => $context }, $class;
}

28 29
sub _context { return $_[0]->{_CONTEXT} }

30
sub process {
31
    my ($self, $hook_name, $template) = @_;
32 33
    my $context = $self->_context();
    $template ||= $context->stash->{component}->{name};
34

35 36
    # sanity check:
    if (!$template =~ /[\w\.\/\-_\\]+/) {
37
        ThrowCodeError('template_invalid', { name => $template });
38
    }
39

40 41 42 43
    my (undef, $path, $filename) = File::Spec->splitpath($template);
    $path ||= '';
    $filename =~ m/(.+)\.(.+)\.tmpl$/;
    my $template_name = $1;
44
    my $type = $2;
45

46
    # Hooks are named like this:
47
    my $extension_template = "$path$template_name-$hook_name.$type.tmpl";
48

49 50 51
    # Get the hooks out of the cache if they exist. Otherwise, read them
    # from the disk.
    my $cache = Bugzilla->request_cache->{template_plugin_hook_cache} ||= {};
52
    my $lang = $context->{bz_language} || '';
53 54
    $cache->{"${lang}__$extension_template"} 
        ||= $self->_get_hooks($extension_template);
55 56 57

    # process() accepts an arrayref of templates, so we just pass the whole
    # arrayref.
58
    $context->{bz_in_hook} = 1; # See Bugzilla::Template::Context
59
    return $context->process($cache->{"${lang}__$extension_template"});
60 61 62 63
}

sub _get_hooks {
    my ($self, $extension_template) = @_;
64

65
    my $template_sets = $self->_template_hook_include_path();
66 67
    my @hooks;
    foreach my $dir_set (@$template_sets) {
68 69
        foreach my $template_dir (@$dir_set) {
            my $file = "$template_dir/hook/$extension_template";
70
            if (-e $file) {
71
                my $template = $self->_context->template($file);
72
                push(@hooks, $template);
73 74
                # Don't run the hook for more than one language.
                last;
75 76 77
            }
        }
    }
78

79
    return \@hooks;
80 81
}

82
sub _template_hook_include_path {
83
    my $self = shift;
84
    my $cache = Bugzilla->request_cache;
85
    my $language = $self->_context->{bz_language} || '';
86
    my $cache_key = "template_plugin_hook_include_path_$language";
87
    $cache->{$cache_key} ||= template_include_path({
88 89
        language => $language,
        hook     => 1,
90
    });
91 92 93
    return $cache->{$cache_key};
}

94 95 96 97 98 99 100 101 102 103 104 105
1;

__END__

=head1 NAME

Bugzilla::Template::Plugin::Hook

=head1 DESCRIPTION

Template Toolkit plugin to process hooks added into templates by extensions.

106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
=head1 METHODS

=over

=item B<process>

=over

=item B<Description>

Processes hooks added into templates by extensions.

=item B<Params>

=over

=item C<hook_name>

The unique name of the template hook.

=item C<template> (optional)

The path of the calling template.
This is used as a work around to a bug which causes the path to the hook
to be incorrect when the hook is called from inside a block.

Example: If the hook C<lastrow> is added to the template
F<show-multiple.html.tmpl> and it is desired to force the correct template
path, the template hook would be:

 [% Hook.process("lastrow", "bug/show-multiple.html.tmpl") %]

=back

=item B<Returns> 

Output from processing template extension.

=back

=back

148 149
=head1 SEE ALSO

150
L<Template::Plugin>
151

152
L<http://wiki.mozilla.org/Bugzilla:Writing_Extensions>