Bug 39522: Allow Valuebuilders to be installable as plugins
This patch adds hooks to allow 'Valuebuilder' plugins to be installable
using the standard plugin architecture for Koha. This enables cataloguing
plugins to be dynamically installed, enabled, and disabled through the
plugin system rather than being hardcoded framework components.
Test plan:
1. Install the example valuebuilder plugin from GitHub
(https://github.com/Jacobomara901/koha-plugin-value-builder)
2. Go to Administration > Plugins
3. Verify the valuebuilder plugin appears in the plugins list
4. Enable/disable the plugin and confirm the custom valuebuilder
appears/disappears in the framework configuration
5. Assign the custom valuebuilder to a MARC subfield in the
bibliographic framework
6. Create/edit a bibliographic record and verify the valuebuilder
button appears next to the configured subfield
7. Click the valuebuilder button and confirm it functions correctly
8. Disable the plugin and verify the valuebuilder button disappears
9. Re-enable the plugin and confirm functionality is restored
10. Uninstall the plugin and verify it's completely removed
Sponsored-by: Open Fifth <https://openfifth.co.uk>
Co-authored-by: Mark Hofstetter <koha@trust-box.at>
Signed-off-by: Catherine Small <c.small@rcs.ac.uk>
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 8e6b687f51)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
This commit is contained in:
parent
1d22b73a5d
commit
9fd2a2cb97
|
|
@ -213,6 +213,37 @@ sub _error {
|
|||
sub _load {
|
||||
my ($self) = @_;
|
||||
|
||||
# Try to find the class that can handle this plugin
|
||||
my @plugins = Koha::Plugins->new()->get_valuebuilders_installed();
|
||||
|
||||
foreach my $vb (@plugins) {
|
||||
my $plugin = $vb->{plugin};
|
||||
|
||||
# Check if this plugin provides the value builder we need
|
||||
if ( $vb->{name} eq $self->{name} ) {
|
||||
|
||||
# Store the plugin object for later use
|
||||
$self->{plugin} = $plugin;
|
||||
|
||||
# Get the builder and launcher directly from the plugin object
|
||||
if ( $plugin->can('builder_code') ) {
|
||||
$self->{builder} = sub { return $plugin->builder_code(@_); };
|
||||
}
|
||||
|
||||
if ( $plugin->can('launcher') ) {
|
||||
$self->{launcher} = sub { return $plugin->launcher(@_); };
|
||||
}
|
||||
|
||||
if ( !$self->{builder} && !$self->{launcher} ) {
|
||||
return $self->_error('Plugin does not contain builder_code nor launcher methods');
|
||||
}
|
||||
|
||||
$self->{_loaded} = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
# If not found via plugin, try in standard dir
|
||||
my ( $rv, $file );
|
||||
return $self->_error('Plugin needs a name') if !$self->{name}; #2chk
|
||||
$self->{path} //= _valuebuilderpath();
|
||||
|
|
@ -291,12 +322,20 @@ sub _generate_js {
|
|||
return $self->_error('Builder sub not defined');
|
||||
}
|
||||
|
||||
# Make a copy of params and add the plugin object to it
|
||||
my $builder_params = {%$params};
|
||||
|
||||
# Add the value builder's plugin if available
|
||||
if ( $self->{name} && $self->{plugin} ) {
|
||||
$builder_params->{plugin} = $self->{plugin};
|
||||
}
|
||||
|
||||
my @params = $self->{oldschool} // 0
|
||||
? (
|
||||
$params->{dbh}, $params->{record}, $params->{tagslib},
|
||||
$params->{id}
|
||||
)
|
||||
: ($params);
|
||||
: ($builder_params);
|
||||
my @rv = &$sub(@params);
|
||||
return $self->_error( 'Builder sub failed: ' . $@ ) if $@;
|
||||
|
||||
|
|
|
|||
|
|
@ -428,6 +428,42 @@ sub _restart_after_change {
|
|||
kill 'HUP', $parent_pid;
|
||||
}
|
||||
|
||||
=head2 get_valuebuilders_installed
|
||||
|
||||
my @valuebuilders = Koha::Plugins->new->get_valuebuilders_installed();
|
||||
|
||||
Returns a list of all valuebuilder plugins provided by plugins.
|
||||
|
||||
=cut
|
||||
|
||||
sub get_valuebuilders_installed {
|
||||
my ($self) = @_;
|
||||
|
||||
# Get ENABLED plugins
|
||||
my @plugins = $self->get_enabled_plugins();
|
||||
|
||||
my @valuebuilders;
|
||||
|
||||
foreach my $plugin (@plugins) {
|
||||
|
||||
# Check if plugin implements get_valuebuilder method
|
||||
if ( $plugin->can('get_valuebuilder') ) {
|
||||
|
||||
# Get the value builder from the plugin
|
||||
my $valuebuilder = $plugin->get_valuebuilder();
|
||||
|
||||
if ($valuebuilder) {
|
||||
push @valuebuilders, {
|
||||
name => $valuebuilder,
|
||||
plugin => $plugin,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return @valuebuilders;
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
|
|
|
|||
|
|
@ -212,6 +212,26 @@ sub get_metadata {
|
|||
return $metadata;
|
||||
}
|
||||
|
||||
=head2 get_valuebuilders
|
||||
|
||||
Get valuebuilder identifier provided by this plugin
|
||||
my $valuebuilder_id = $plugin->get_valuebuilders();
|
||||
|
||||
=cut
|
||||
|
||||
sub get_valuebuilders {
|
||||
my ($self) = @_;
|
||||
|
||||
# If this plugin has a get_valuebuilder method that returns a non-empty value,
|
||||
# return that value in an array reference
|
||||
if ( $self->can('get_valuebuilder') ) {
|
||||
my $vb = $self->get_valuebuilder();
|
||||
return $vb ? [$vb] : [];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
=head2 get_qualified_table_name
|
||||
|
||||
To avoid naming conflict, each plugins tables should use a fully qualified namespace.
|
||||
|
|
@ -403,6 +423,22 @@ sub disable {
|
|||
return $self;
|
||||
}
|
||||
|
||||
=head2 get_valuebuilder_url
|
||||
|
||||
Returns the full URL to launch this plugin's value builder
|
||||
|
||||
my $url = $plugin->get_valuebuilder_url();
|
||||
|
||||
=cut
|
||||
|
||||
sub get_valuebuilder_url {
|
||||
my ($self) = @_;
|
||||
|
||||
# Generate the URL to run.pl with the launcher method
|
||||
my $plugin_class = ref($self);
|
||||
return "/cgi-bin/koha/plugins/run.pl?class=$plugin_class&method=launcher";
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
|
|
|
|||
|
|
@ -126,6 +126,31 @@ if ( $op eq 'add_form' ) {
|
|||
@value_builder = sort { $a cmp $b } @value_builder;
|
||||
closedir $dir_h;
|
||||
|
||||
# Add valuebuilders from plugins
|
||||
if ( C4::Context->config("enable_plugins") ) {
|
||||
require Koha::Plugins;
|
||||
my $plugins = Koha::Plugins->new();
|
||||
|
||||
# Get all plugins first to debug
|
||||
my @all_plugins = $plugins->GetPlugins();
|
||||
foreach my $plugin (@all_plugins) {
|
||||
( $plugin->can('get_valuebuilders') ? "yes" : "no" );
|
||||
}
|
||||
|
||||
# Use the dedicated get_valuebuilders_installed method
|
||||
my @plugin_valuebuilders = $plugins->get_valuebuilders_installed();
|
||||
|
||||
foreach my $vb_entry (@plugin_valuebuilders) {
|
||||
my $vb_name = $vb_entry->{name};
|
||||
|
||||
# Avoid duplicates
|
||||
push( @value_builder, $vb_name ) unless grep { $_ eq $vb_name } @value_builder;
|
||||
}
|
||||
|
||||
# Re-sort the list after adding plugin valuebuilders
|
||||
@value_builder = sort { $a cmp $b } @value_builder;
|
||||
}
|
||||
|
||||
# build values list
|
||||
my $mss = Koha::MarcSubfieldStructures->search(
|
||||
{ tagfield => $tagfield, frameworkcode => $frameworkcode },
|
||||
|
|
|
|||
Loading…
Reference in New Issue