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>
This commit is contained in:
parent
77ee024313
commit
8e6b687f51
|
|
@ -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