Bug 28026: Add call_recursive() as a supplement for call()

The method call() is not sufficient for all plugin hook types. It's
possible that more than one plugin will be installed that wants to
return the arguaments passed in an updated form.  These transformation
plugins need to work recursively rather than independantly.

This patch adss a `call_recursive()` method that takes the output of
the first plugin and uses it as the input for the next plugin and so
on. This allowes each plugin to see the current version of the arguament
list and modify it as necessary.

Test plan
1/ Run the included tests - t/db_dependent/Koha/Plugins/Plugins.t

Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
This commit is contained in:
Kyle Hall 2021-03-23 16:07:20 +00:00 committed by Jonathan Druart
parent 7ce74ab133
commit fc68d49897
3 changed files with 72 additions and 1 deletions

View file

@ -85,6 +85,41 @@ sub call {
return @responses;
}
=head2 call_recursive
Calls a plugin method for all enabled plugins,
passing the return value from the previous plugin
to the next one.
@response = Koha::Plugins->call_recursive($method, @args)
=cut
sub call_recursive {
my ( $class, $method, @args ) = @_;
my @responses;
if ( C4::Context->config('enable_plugins') ) {
my @plugins = $class->new( { enable_plugins => 1 } )->GetPlugins( { method => $method } );
@plugins = grep { $_->can($method) } @plugins;
foreach my $plugin (@plugins) {
my @response = eval { $plugin->$method(@args) };
if ($@) {
warn sprintf( "Plugin error (%s): %s", $plugin->get_metadata->{name}, $@ );
next;
} else {
@args = @response;
}
}
}
return @args;
}
=head2 GetPlugins
This will return a list of all available plugins, optionally limited by

View file

@ -25,7 +25,7 @@ use File::Temp qw( tempdir tempfile );
use FindBin qw($Bin);
use Module::Load::Conditional qw(can_load);
use Test::MockModule;
use Test::More tests => 58;
use Test::More tests => 59;
use Test::Warn;
use C4::Context;
@ -86,6 +86,36 @@ subtest 'call() tests' => sub {
$schema->storage->txn_rollback;
};
subtest 'call_recursive() tests' => sub {
plan tests => 6;
$schema->storage->txn_begin;
# Temporarily remove any installed plugins data
Koha::Plugins::Methods->delete;
t::lib::Mocks::mock_config('enable_plugins', 1);
my $plugins = Koha::Plugins->new({ enable_plugins => 1 });
my @plugins = $plugins->InstallPlugins;
foreach my $plugin (@plugins) {
$plugin->enable();
}
my (@responses) = Koha::Plugins->call_recursive('test_call_recursive', 1);
is( scalar @responses, 1, "Got back one element" );
is( $responses[0], 11, "Got expected response" );
(@responses) = Koha::Plugins->call_recursive('test_call_recursive', 'abcd');
is( scalar @responses, 1, "Got back one element" );
is( $responses[0], 'abcdabcd', "Got expected response" );
t::lib::Mocks::mock_config('enable_plugins', 0);
(@responses) = Koha::Plugins->call_recursive('test_call_recursive', 1);
is( scalar @responses, 1, "Got back one element" );
is( $responses[0], 1, "call_recursive should return the original arguments if plugins are disabled" );
$schema->storage->txn_rollback;
};
subtest 'GetPlugins() tests' => sub {
plan tests => 3;

View file

@ -308,6 +308,12 @@ sub intranet_catalog_biblio_tab {
return @tabs;
}
sub test_call_recursive {
my ( $self, $value ) = @_;
return $value x 2;
}
sub _private_sub {
return "";
}