From 9af999aa04e4685fd19902e4d4d7f8dc9525224b Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Thu, 9 Oct 2025 13:22:38 +0100 Subject: [PATCH] Bug 40984: Synchronize before_ and after_authority_action hooks with biblio action hooks This patch updates the authority action plugin hooks to match the signature and behavior of the biblio action hooks: 1. Created before_authority_action hook that is called before authority records are saved, allowing plugins to modify records before they are stored in the database 2. Updated after_authority_action hook to use a payload parameter containing authority, authority_id, and record, matching the pattern used by after_biblio_action hook 3. Maintained backward compatibility by passing both old parameters (authority, authority_id) and new payload parameter, with deprecation warnings logged when plugins implement the hook 4. Updated test plugin to use new payload-based signatures for both hooks 5. Added test coverage for before_authority_action hook Test plan: 1. Run: prove t/db_dependent/Koha/Plugins/authority_hooks.t 2. Run: prove t/db_dependent/Koha/Plugins/ 3. All tests should pass --- C4/AuthoritiesMarc.pm | 61 ++++++++++++++++++- t/db_dependent/Koha/Plugins/authority_hooks.t | 23 ++++++- t/lib/plugins/Koha/Plugin/Test.pm | 19 +++++- 3 files changed, 97 insertions(+), 6 deletions(-) diff --git a/C4/AuthoritiesMarc.pm b/C4/AuthoritiesMarc.pm index 581ab42eca7..bf51a613e92 100644 --- a/C4/AuthoritiesMarc.pm +++ b/C4/AuthoritiesMarc.pm @@ -39,6 +39,8 @@ use Koha::Authority; use Koha::Database; use Koha::Libraries; use Koha::RecordProcessor; +use Koha::Logger; +use Koha::Plugins; use Koha::SearchEngine; use Koha::SearchEngine::Indexer; use Koha::SearchEngine::Search; @@ -673,6 +675,9 @@ sub AddAuthority { $p->process($record); } + # Call before hook + _before_authority_action_hooks( { action => 'save', authority_id => $authid, record => $record } ); + # Save record into auth_header, update 001 my $action; my $authority; @@ -1885,6 +1890,25 @@ sub compare_fields { return 1; } +=head2 _before_authority_action_hooks + +Helper method that takes care of calling all plugin hooks before an authority action + +=cut + +sub _before_authority_action_hooks { + my ($args) = @_; + + my $authority_id = $args->{authority_id}; + my $record = $args->{record}; + my $action = $args->{action} // q{}; + + Koha::Plugins->call( + 'before_authority_action', + { action => $action, payload => { authority_id => $authority_id, record => $record } } + ); +} + =head2 _after_authority_action_hooks Helper method that takes care of calling all plugin hooks @@ -1892,11 +1916,42 @@ Helper method that takes care of calling all plugin hooks =cut sub _after_authority_action_hooks { - my ($args) = @_; # hash keys: action, authority_id - return Koha::Plugins->call( 'after_authority_action', $args ); + my ($args) = @_; + + my $authority_id = $args->{authority_id}; + my $action = $args->{action} // q{}; + + my $authority = $action ne 'delete' ? Koha::Authorities->find($authority_id) : undef; + my $record = $authority ? $authority->record : undef; + + Koha::Plugins->call( + 'after_authority_action', + { + action => $action, + payload => { + authority => $authority, + authority_id => $authority_id, + record => $record, + }, + + # NOTE: Deprecated parameters, will be removed in a future release + authority => $authority, + authority_id => $authority_id, + } + ); + + # Log deprecation warning if any plugin is still using the old signature + my @plugins = Koha::Plugins->get_enabled_plugins( { verbose => 0 } ); + @plugins = grep { $_->can('after_authority_action') } @plugins; + if (@plugins) { + Koha::Logger->get->warn( + "after_authority_action hook: The old signature (with authority and authority_id as direct parameters) " + . "is deprecated and will be removed in a future release. " + . "Please update your plugin to use the 'payload' parameter instead." ); + } } -END { } # module clean-up code here (global destructor) +END { } # module clean-up code here (global destructor) 1; __END__ diff --git a/t/db_dependent/Koha/Plugins/authority_hooks.t b/t/db_dependent/Koha/Plugins/authority_hooks.t index 14a69b51e4b..44a8530bf5d 100755 --- a/t/db_dependent/Koha/Plugins/authority_hooks.t +++ b/t/db_dependent/Koha/Plugins/authority_hooks.t @@ -18,7 +18,7 @@ use Modern::Perl; use MARC::Record; use Test::NoWarnings; -use Test::More tests => 5; +use Test::More tests => 6; use Test::Warn; use File::Basename; @@ -44,6 +44,27 @@ my $builder = t::lib::TestBuilder->new; t::lib::Mocks::mock_config( 'enable_plugins', 1 ); +subtest 'before_authority_action hook' => sub { + plan tests => 1; + + $schema->storage->txn_begin; + + my $plugins = Koha::Plugins->new; + $plugins->InstallPlugins; + my $plugin = Koha::Plugin::Test->new->enable; + + my $record = MARC::Record->new; + $record->append_fields( MARC::Field->new( '100', '1', '2', a => 'Name' ) ); + my $type = $builder->build( { source => 'AuthType', value => { auth_tag_to_report => '100' } } ); + + warnings_exist { C4::AuthoritiesMarc::AddAuthority( $record, undef, $type->{authtypecode} ); } + qr/before_authority_action called with action: save, authority_id: /, + 'AddAuthority calls the before hook with action=save'; + + Koha::Plugins->RemovePlugins; + $schema->storage->txn_rollback; +}; + subtest 'after_authority_action hook' => sub { plan tests => 3; diff --git a/t/lib/plugins/Koha/Plugin/Test.pm b/t/lib/plugins/Koha/Plugin/Test.pm index 46f0732dc6a..63cdd416106 100644 --- a/t/lib/plugins/Koha/Plugin/Test.pm +++ b/t/lib/plugins/Koha/Plugin/Test.pm @@ -215,10 +215,25 @@ sub after_item_action { } } +sub before_authority_action { + my ( $self, $params ) = @_; + + my $action = $params->{action} // ''; + my $payload = $params->{payload}; + my $authority_id = $payload->{authority_id} // ''; + my $record = $payload->{record}; + + Koha::Exception->throw("before_authority_action called with action: $action, authority_id: $authority_id"); +} + sub after_authority_action { my ( $self, $params ) = @_; - my $action = $params->{action} // q{}; - my $id = $params->{authority_id} // 0; + my $action = $params->{action} // q{}; + my $payload = $params->{payload}; + my $authority = $payload->{authority}; + my $id = $payload->{authority_id} // 0; + my $record = $payload->{record}; + Koha::Exception->throw("after_authority_action called with action: $action, id: $id"); } -- 2.51.0