@@ -, +, @@ 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) Look in plugin_data for the new "__METADATA__" key, note it has the metadata in it 4) Alter the metadata in KitchenSink.pm, delete __METADATA__ from plugin_data 5) Browse to plugins home, note that nothing appears to have changed 6) Note the metadata in plugin_data has been regenerated 7) Browse to your pluginsdir, find the KitchenSink.pm file for the Kitchen Sink plugin, edit some of the metadata 8) Delete the plugin_data metadata again 9) Reload the plugins home --- Koha/Plugins.pm | 94 ++++++++++++++++++- Koha/Plugins/Base.pm | 25 ++++- Koha/Plugins/Data.pm | 54 +++++++++++ Koha/Plugins/Datum.pm | 44 +++++++++ .../prog/en/modules/plugins/plugins-home.tt | 48 +++++----- plugins/plugins-home.pl | 4 +- 6 files changed, 239 insertions(+), 30 deletions(-) create mode 100644 Koha/Plugins/Data.pm create mode 100644 Koha/Plugins/Datum.pm --- a/Koha/Plugins.pm +++ a/Koha/Plugins.pm @@ -21,17 +21,21 @@ use Modern::Perl; use Class::Inspector; 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(Load Dump); use C4::Context; use C4::Output; use Koha::Plugins::Methods; +use Koha::Plugins::Data; + +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,82 @@ 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 @plugins; + while ( my $plugin_class = $plugin_classes->next ) { + my $plugin_metadata = Koha::Plugins::Data->find( + { + plugin_class => $plugin_class, + plugin_key => '__METADATA__', + } + ); + + if ( $plugin_metadata ) { + $plugin_metadata = YAML::Load( $plugin_metadata->plugin_value ); + } + else { + load $plugin_class; + my $plugin = $plugin_class->new( + { + enable_plugins => $self->{enable_plugins} + } + ); + $plugin_metadata = $plugin->get_metadata; + + Koha::Plugins::Datum->new( + { + plugin_class => $plugin_class, + plugin_key => '__METADATA__', + plugin_value => YAML::Dump( $plugin_metadata ), + } + )->store(); + } + + my $plugin_enabled = Koha::Plugins::Data->find( + { + plugin_class => $plugin_class, + plugin_key => '__ENABLED__', + } + ); + $plugin_metadata->{is_enabled} = $plugin_enabled->plugin_value; + + my @plugin_methods = Koha::Plugins::Methods->search( + { + plugin_class => $plugin_class, + }, + { + columns => 'plugin_method', + } + ); + $plugin_metadata->{can}->{ $_->plugin_method } = 1 foreach @plugin_methods; + warn Data::Dumper::Dumper( $plugin_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() @@ -137,6 +217,16 @@ sub InstallPlugins { my $plugin = $plugin_class->new({ enable_plugins => $self->{'enable_plugins'} }); + # Force update plugin metadata in the database + my $metadata = $plugin->get_metadata( { skip_database => 1 } ); + my $params = { + plugin_class => $plugin_class, + plugin_key => 'metadata', + }; + my $db_metadata = Koha::Plugins::Data->find( $params ) || Koha::Plugins::Datum->new( $params ); + $db_metadata->plugin_value( YAML::Dump($metadata) ); + $db_metadata->store(); + Koha::Plugins::Methods->search({ plugin_class => $plugin_class })->delete(); foreach my $method ( @{ Class::Inspector->methods( $plugin_class, 'public' ) } ) { --- a/Koha/Plugins/Base.pm +++ a/Koha/Plugins/Base.pm @@ -19,9 +19,10 @@ package Koha::Plugins::Base; use Modern::Perl; -use Module::Pluggable require => 1; use Cwd qw(abs_path); use List::Util qw(max); +use Module::Pluggable require => 1; +use YAML qw(Load LoadFile); use base qw{Module::Bundled::Files}; @@ -177,8 +178,28 @@ sub get_template { sub get_metadata { my ( $self, $args ) = @_; + my $skip_database = $args->{skip_database}; + + my $metadata = $self->{metadata}; # Check for old style metadata in blessed hash + $metadata ||= $self::metadata; # Check for a global metadata var ( i.e. our $metadata ) + + unless ( $metadata && !$skip_database ) { # Check the database next, unless this is a plugin upgrade + $metadata = $self->retrieve_data('__METADATA__'); + $metadata = YAML::Load( $metadata ); + } + + unless ( $metadata ) { # Check for metadata in PLUGIN.yml, if it exists + my $bundle_path = $self->bundle_path; + my $plugin_yml = "$bundle_path/PLUGIN.yml"; + if ( -r $plugin_yml ) { + $metadata = YAML::LoadFile( $plugin_yml ); + } + } + + my $class = ref($self); + $metadata->{class} = $class; + #FIXME: Why another encoding issue? For metadata containing non latin characters. - my $metadata = $self->{metadata}; $metadata->{$_} && utf8::decode($metadata->{$_}) for keys %$metadata; return $metadata; } --- a/Koha/Plugins/Data.pm +++ a/Koha/Plugins/Data.pm @@ -0,0 +1,54 @@ +package Koha::Plugins::Data; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Carp; + +use Koha::Database; + +use Koha::Plugins::Datum; + +use base qw(Koha::Objects); + +=head1 NAME + +Koha::Plugin::Data - Koha Plugins Data Object set class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 type + +=cut + +sub _type { + return 'PluginData'; +} + +=head3 object_class + +=cut + +sub object_class { + return 'Koha::Plugins::Datum'; +} + +1; --- a/Koha/Plugins/Datum.pm +++ a/Koha/Plugins/Datum.pm @@ -0,0 +1,44 @@ +package Koha::Plugins::Datum; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Carp; + +use Koha::Database; + +use base qw(Koha::Object); + +=head1 NAME + +Koha::Plugin::Datum - Koha Plugin Data Object class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 type + +=cut + +sub _type { + return 'PluginData'; +} + +1; --- a/koha-tmpl/intranet-tmpl/prog/en/modules/plugins/plugins-home.tt +++ a/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,66 +113,66 @@ [% END %] - [% FOREACH plugin IN plugins %] + [% FOREACH metadata IN plugins_metadata %] - [% plugin.metadata.name | html %] - [% IF ( plugin.is_enabled ) %] + [% metadata.name | html %] + [% IF ( metadata.is_enabled ) %] ENABLED [% ELSE %] DISABLED [% 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 ) %]
- + Actions -