@@ -, +, @@ https://github.com/bywatersolutions/koha-plugin-kitchen-sink/releases plugin has never been upgraded was upgraded and give you the date and time of the upgrade --- Koha/Plugins/Base.pm | 51 +++++++++++++++++++++++++++++++++++++++++++++++ t/db_dependent/Plugins.t | 18 +++++++++++++++-- t/lib/Koha/Plugin/Test.pm | 5 +++++ 3 files changed, 72 insertions(+), 2 deletions(-) --- a/Koha/Plugins/Base.pm +++ a/Koha/Plugins/Base.pm @@ -21,6 +21,7 @@ use Modern::Perl; use Module::Pluggable require => 1; use Cwd qw(abs_path); +use List::Util qw(max); use base qw{Module::Bundled::Files}; @@ -43,13 +44,26 @@ sub new { my $self = bless( $args, $class ); + my $plugin_version = $self->get_metadata->{version}; + my $database_version = $self->retrieve_data('__INSTALLED_VERSION__'); + ## Run the installation method if it exists and hasn't been run before if ( $self->can('install') && !$self->retrieve_data('__INSTALLED__') ) { if ( $self->install() ) { $self->store_data( { '__INSTALLED__' => 1 } ); + if ( my $version = $plugin_version ) { + $self->store_data({ '__INSTALLED_VERSION__' => $version }); + } } else { warn "Plugin $class failed during installation!"; } + } elsif ( $self->can('upgrade') && $plugin_version && $database_version ) { + if ( _version_compare( $plugin_version, $database_version ) == 1 ) { + if ( $self->upgrade() ) { + $self->store_data({ '__INSTALLED_VERSION__' => $plugin_version }); + warn "Plugin $class failed during upgrade!"; + } + } } return $self; @@ -218,6 +232,43 @@ sub output { output_with_http_headers( $self->{cgi}, undef, $data, $content_type, $status, $extra_options ); } +=head2 _version_compare + +Utility method to compare two version numbers. +Returns 1 if the first argument is the higher version +Returns -1 if the first argument is the lower version +Returns 0 if both versions are equal + +if ( _version_compare( '2.6.26', '2.6.0' ) == 1 ) { + print "2.6.26 is greater than 2.6.0\n"; +} + +=cut + +sub _version_compare { + my $ver1 = shift || 0; + my $ver2 = shift || 0; + + my @v1 = split /[.+:~-]/, $ver1; + my @v2 = split /[.+:~-]/, $ver2; + + for ( my $i = 0 ; $i < max( scalar(@v1), scalar(@v2) ) ; $i++ ) { + + # Add missing version parts if one string is shorter than the other + # i.e. 0 should be lt 0.2.1 and not equal, so we append .0 + # 0.0.0 <=> 0.2.1 = -1 + push( @v1, 0 ) unless defined( $v1[$i] ); + push( @v2, 0 ) unless defined( $v2[$i] ); + if ( int( $v1[$i] ) > int( $v2[$i] ) ) { + return 1; + } + elsif ( int( $v1[$i] ) < int( $v2[$i] ) ) { + return -1; + } + } + return 0; +} + 1; __END__ --- a/t/db_dependent/Plugins.t +++ a/t/db_dependent/Plugins.t @@ -2,15 +2,15 @@ use Modern::Perl; -use Test::More tests => 35; +use Archive::Extract; use CGI; use File::Basename; use File::Spec; use File::Temp qw( tempdir tempfile ); use FindBin qw($Bin); -use Archive::Extract; use Module::Load::Conditional qw(can_load); use Test::MockModule; +use Test::More tests => 37; use C4::Context; use t::lib::Mocks; @@ -49,6 +49,7 @@ ok( $plugin->can('opac_head'), 'Test plugin can opac_head' ); ok( $plugin->can('opac_js'), 'Test plugin can opac_js' ); ok( $plugin->can('configure'), 'Test plugin can configure' ); ok( $plugin->can('install'), 'Test plugin can install' ); +ok( $plugin->can('upgrade'), 'Test plugin can upgrade' ); ok( $plugin->can('uninstall'), 'Test plugin can install' ); is( Koha::Plugins::Handler->run({ class => "Koha::Plugin::Test", method => 'report', enable_plugins => 1 }), "Koha::Plugin::Test::report", 'Test run plugin report method' ); @@ -151,3 +152,16 @@ subtest 'output and output_html tests' => sub { like($stdout, qr{Content-Type: text/html; charset=UTF-8}, 'Correct content-type'); like($stdout, qr{¡Hola output_html!}, 'Correct data'); }; + +subtest 'Test _version_compare' => sub { + + plan tests => 6; + + is( Koha::Plugins::Base::_version_compare( '1.1.1', '2.2.2' ), -1, "1.1.1 is less then 2.2.2" ); + is( Koha::Plugins::Base::_version_compare( '2.2.2', '1.1.1' ), 1, "1.1.1 is greater then 2.2.2" ); + is( Koha::Plugins::Base::_version_compare( '1.1.1', '1.1.1' ), 0, "1.1.1 is equal to 1.1.1" ); + is( Koha::Plugins::Base::_version_compare( '1.01.001', '1.1.1' ), 0, "1.01.001 is equal to 1.1.1" ); + is( Koha::Plugins::Base::_version_compare( '1', '1.0.0' ), 0, "1 is equal to 1.0.0" ); + is( Koha::Plugins::Base::_version_compare( '1.0', '1.0.0' ), 0, "1.0 is equal to 1.0.0" ); +}; + --- a/t/lib/Koha/Plugin/Test.pm +++ a/t/lib/Koha/Plugin/Test.pm @@ -78,6 +78,11 @@ sub install { return "Koha::Plugin::Test::install"; } +sub upgrade { + my ( $self, $args ) = @_; + return "Koha::Plugin::Test::install"; +} + sub uninstall { my ( $self, $args ) = @_; return "Koha::Plugin::Test::uninstall"; --