From fc68d49897900fb365e3016ba38fbc10be77d14f Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Tue, 23 Mar 2021 16:07:20 +0000 Subject: [PATCH] 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 Signed-off-by: Tomas Cohen Arazi Signed-off-by: Jonathan Druart --- Koha/Plugins.pm | 35 +++++++++++++++++++++++++++ t/db_dependent/Koha/Plugins/Plugins.t | 32 +++++++++++++++++++++++- t/lib/Koha/Plugin/Test.pm | 6 +++++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/Koha/Plugins.pm b/Koha/Plugins.pm index fa4d235287..5cb9107cdb 100644 --- a/Koha/Plugins.pm +++ b/Koha/Plugins.pm @@ -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 diff --git a/t/db_dependent/Koha/Plugins/Plugins.t b/t/db_dependent/Koha/Plugins/Plugins.t index 8003165895..69cbffdfde 100755 --- a/t/db_dependent/Koha/Plugins/Plugins.t +++ b/t/db_dependent/Koha/Plugins/Plugins.t @@ -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; diff --git a/t/lib/Koha/Plugin/Test.pm b/t/lib/Koha/Plugin/Test.pm index 8ca9babff4..151af98476 100644 --- a/t/lib/Koha/Plugin/Test.pm +++ b/t/lib/Koha/Plugin/Test.pm @@ -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 ""; } -- 2.39.5