From 894d792f0641ebee1c0d175877832a74d004002d Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Thu, 16 Apr 2020 11:50:28 -0400 Subject: [PATCH] Bug 24631: Plugin metadata should be outside the main class Currently, plugin metadata is stored within the main plugin class file but this means one has to load the class to read it. We should pull this data out into a manifest/metadata file in a standard format (JSON/YAML) to allow simpler external parsing. Test Plan: 1) Apply this patch 2) Install the latest Kitchen Sink plugin: https://github.com/bywatersolutions/koha-plugin-kitchen-sink/releases/download/v2.1.39/koha-plugin-kitchen-sink-v2.1.39.kpz 3) Browse to plugins home, note that nothing appears to have changed 4) Browse to your pluginsdir, find the PLUGIN.yml file for the Kitchen Sink plugin, edit some of the metadata 5) Reload the plugins home page, note your changes to PLUGIN.yml appear in the plugins table! Signed-off-by: Victor Grousset/tuxayo --- Koha/Plugins.pm | 60 ++++++++++++++++++- cpanfile | 1 + .../prog/en/modules/plugins/plugins-home.tt | 28 ++++----- plugins/plugins-home.pl | 4 +- 4 files changed, 75 insertions(+), 18 deletions(-) diff --git a/Koha/Plugins.pm b/Koha/Plugins.pm index 9dc42c5155..b7b674f071 100644 --- a/Koha/Plugins.pm +++ b/Koha/Plugins.pm @@ -20,18 +20,22 @@ package Koha::Plugins; use Modern::Perl; use Class::Inspector; +use File::Find::Rule; use List::MoreUtils qw(any); -use Module::Load::Conditional qw(can_load); use Module::Load qw(load); +use Module::Load::Conditional qw(can_load); use Module::Pluggable search_path => ['Koha::Plugin'], except => qr/::Edifact(|::Line|::Message|::Order|::Segment|::Transport)$/; +use YAML qw(LoadFile); use C4::Context; use C4::Output; use Koha::Plugins::Methods; +our @pluginsdir; + BEGIN { my $pluginsdir = C4::Context->config("pluginsdir"); - my @pluginsdir = ref($pluginsdir) eq 'ARRAY' ? @$pluginsdir : $pluginsdir; + @pluginsdir = ref($pluginsdir) eq 'ARRAY' ? @$pluginsdir : $pluginsdir; push( @INC, @pluginsdir ); pop @INC if $INC[-1] eq '.'; } @@ -112,6 +116,58 @@ sub GetPlugins { return @plugins; } +sub GetPluginsMetadata { + my ( $self, $params ) = @_; + + my $method = $params->{method}; + my $req_metadata = $params->{metadata} // {}; + + my $filter = ( $method ) ? { plugin_method => $method } : undef; + + my $plugin_classes = Koha::Plugins::Methods->search( + $filter, + { columns => 'plugin_class', + distinct => 1 + } + )->_resultset->get_column('plugin_class'); + + my @metafiles = File::Find::Rule->file()->name('PLUGIN.yml')->in( @pluginsdir ); + + my @plugins; + while ( my $plugin_class = $plugin_classes->next ) { + my $plugin_path = $plugin_class; + $plugin_path =~ s/::/\//g; # Take class name, transform :: to / to get path + my $yaml_to_find = "$plugin_path/PLUGIN.yml"; + $plugin_path =~ s/$/.pm/; # Add .pm to the end + + # Find the full path to the file, it's somewhere in the list of metafiles we found when this module as loaded + my ( $meta_yaml ) = grep { $yaml_to_find eq substr( $_, -length($yaml_to_find) ) } @metafiles; + + my $plugin_metadata; + if ( -r $meta_yaml ) { # If the metafile exists and is readable, use it + $plugin_metadata = YAML::LoadFile($meta_yaml); + } else { # Fall back to loading the plugin to get the metadata if there is no PLUGIN.yml file to read + load $plugin_class; + my $plugin = $plugin_class->new({ + enable_plugins => $self->{'enable_plugins'} + }); + + # filter the plugin out by metadata + $plugin_metadata = $plugin->get_metadata; + } + + next + if $plugin_metadata + and %$req_metadata + and any { !$plugin_metadata->{$_} || $plugin_metadata->{$_} ne $req_metadata->{$_} } keys %$req_metadata; + + push @plugins, $plugin_metadata; + + } + + return @plugins; +} + =head2 InstallPlugins Koha::Plugins::InstallPlugins() diff --git a/cpanfile b/cpanfile index f7d69c3f84..048d8d9620 100644 --- a/cpanfile +++ b/cpanfile @@ -39,6 +39,7 @@ requires 'Email::Date', '1.103'; requires 'Email::MessageID', '1.406'; requires 'Email::Valid', '0.190'; requires 'Exception::Class', '1.38'; +requires 'File::Find::Rule', '0.34'; requires 'File::Slurp', '9999.13'; requires 'Font::TTF', '0.45'; requires 'GD', '2.39'; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/plugins/plugins-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/plugins/plugins-home.tt index 1c25a22718..df399f3d66 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/plugins/plugins-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/plugins/plugins-home.tt @@ -80,7 +80,7 @@ [% END %] - [% UNLESS ( plugins ) %] + [% UNLESS ( plugins_metadata ) %] [% UNLESS ( method ) %]
No plugins installed
[% ELSE %] @@ -113,10 +113,10 @@ [% END %] - [% FOREACH plugin IN plugins %] + [% FOREACH metadata IN plugins_metadata %] - [% plugin.metadata.name | html %] + [% metadata.name | html %] [% IF ( plugin.is_enabled ) %] ENABLED [% ELSE %] @@ -124,25 +124,25 @@ [% END %] - [% plugin.metadata.description | html %] + [% metadata.description | html %] - [% IF ( plugin.metadata.minimum_version && koha_version < plugin.metadata.minimum_version ) %] + [% IF ( metadata.minimum_version && koha_version < metadata.minimum_version ) %]
Warning: This report was written for a newer version of Koha. Run at your own risk.
[% END %] - [% IF ( plugin.metadata.maximum_version && koha_version > plugin.metadata.maximum_version ) %] + [% IF ( metadata.maximum_version && koha_version > metadata.maximum_version ) %]
Warning: This plugin was written for an older version of Koha. Run at your own risk.
[% END %] - [% plugin.metadata.author | html %] - [% plugin.metadata.version | html %] - [% plugin.metadata.minimum_version | html %] - [% plugin.metadata.maximum_version | html %] - [% plugin.metadata.date_updated | $KohaDates %] + [% metadata.author | html %] + [% metadata.version | html %] + [% metadata.minimum_version | html %] + [% metadata.maximum_version | html %] + [% metadata.date_updated | $KohaDates %] [% IF ( CAN_user_plugins_configure || CAN_user_plugins_manage || CAN_user_plugins_report || CAN_user_plugins_tool ) %]