From ecbdca8c3f06dd420db6a960c8808615dae6848a Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Sat, 1 Apr 2017 10:45:25 -0400 Subject: Bug 1352913 - Extensions must register for template_before_process() We can skip a lot of method calls if extensions must declare what templates they act on. --- Bugzilla/Hook.pm | 44 +++++++++++++++++++++++++++++--------------- Bugzilla/Template/Context.pm | 23 +++++++++++++++++------ 2 files changed, 46 insertions(+), 21 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Hook.pm b/Bugzilla/Hook.pm index 00bd316ab..e28c01a40 100644 --- a/Bugzilla/Hook.pm +++ b/Bugzilla/Hook.pm @@ -11,18 +11,42 @@ use 5.10.1; use strict; use warnings; +use Scalar::Util qw(blessed); + sub process { - my ($name, $args) = @_; + my ($name, $args, $extensions) = @_; + + $extensions //= Bugzilla->extensions; + + my $hook_stack = Bugzilla->request_cache->{hook_stack} ||= []; + push @$hook_stack, $name; + + foreach my $extension (@$extensions) { + if (my $hook = $extension->can($name)) { + $hook->($extension, $args); + } + } - _entering($name); + pop @$hook_stack; +} + +sub collect_wants { + my ($name) = @_; + my %result; foreach my $extension (@{ Bugzilla->extensions }) { - if ($extension->can($name)) { - $extension->$name($args); + my $hook = $extension->can($name); + if ($hook) { + my $wants = $hook->($extension); + foreach my $want (keys %$wants) { + if ($wants->{$want}) { + $result{ $want }{ blessed $extension } = 1; + } + } } } - _leaving($name); + return \%result; } sub in { @@ -31,16 +55,6 @@ sub in { return $hook_name eq $currently_in ? 1 : 0; } -sub _entering { - my ($hook_name) = @_; - my $hook_stack = Bugzilla->request_cache->{hook_stack} ||= []; - push(@$hook_stack, $hook_name); -} - -sub _leaving { - pop @{ Bugzilla->request_cache->{hook_stack} }; -} - 1; __END__ diff --git a/Bugzilla/Template/Context.pm b/Bugzilla/Template/Context.pm index b81e32130..e78cd9806 100644 --- a/Bugzilla/Template/Context.pm +++ b/Bugzilla/Template/Context.pm @@ -69,13 +69,24 @@ sub stash { # template object for Throw*Error). # # Checking Bugzilla::Hook::in prevents infinite recursion on this hook. - if ($self->{bz_in_process} and $name =~ /\./ - and !grep($_ eq $name, @$pre_process) - and !Bugzilla::Hook::in('template_before_process')) + + if ( $self->{bz_in_process} + and $name =~ /\./ + and !grep( $_ eq $name, @$pre_process ) + and !Bugzilla::Hook::in('template_before_process') ) { - Bugzilla::Hook::process("template_before_process", - { vars => $stash, context => $self, - file => $name }); + state $WANT = Bugzilla::Hook::collect_wants('template_before_process_wants'); + if ( $WANT->{$name} ) { + my @extensions = grep { $WANT->{$name}{ blessed $_ } } @{ Bugzilla->extensions }; + Bugzilla::Hook::process( + "template_before_process" => { + vars => $stash, + context => $self, + file => $name + }, + \@extensions + ) if @extensions; + } } # This prevents other calls to stash() that might somehow happen -- cgit v1.2.3-24-g4f1b