@@ -, +, @@ --- C4/Images.pm | 235 ------------------ Koha/Biblio.pm | 15 ++ Koha/CoverImage.pm | 116 +++++++++ Koha/CoverImages.pm | 71 ++++++ Koha/Item.pm | 16 ++ catalogue/detail.pl | 10 +- catalogue/image.pl | 55 ++-- catalogue/imageviewer.pl | 13 +- installer/data/mysql/kohastructure.sql | 2 +- .../prog/en/modules/catalogue/detail.tt | 28 +-- .../prog/en/modules/catalogue/imageviewer.tt | 28 +-- .../bootstrap/en/modules/opac-detail.tt | 8 +- .../bootstrap/en/modules/opac-imageviewer.tt | 22 +- opac/opac-detail.pl | 8 +- opac/opac-image.pl | 54 ++-- opac/opac-imageviewer.pl | 10 +- svc/cover_images | 4 +- t/Images.t | 71 ------ t/db_dependent/Koha/CoverImages.t | 19 +- tools/upload-cover-image.pl | 47 +++- 20 files changed, 377 insertions(+), 455 deletions(-) delete mode 100644 C4/Images.pm create mode 100644 Koha/CoverImage.pm create mode 100644 Koha/CoverImages.pm delete mode 100755 t/Images.t --- a/C4/Images.pm +++ a/C4/Images.pm @@ -1,235 +0,0 @@ -package C4::Images; - -# Copyright (C) 2011 C & P Bibliography Services -# Jared Camins-Esakov -# -# 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 C4::Context; -use GD; -use Koha::Exceptions; - -use vars qw($debug $noimage @ISA @EXPORT); - -BEGIN { - - require Exporter; - @ISA = qw(Exporter); - @EXPORT = qw( - &PutImage - &RetrieveImage - &ListImagesForBiblio - &DelImage - ); - $debug = $ENV{KOHA_DEBUG} || $ENV{DEBUG} || 0; - - $noimage = pack( "H*", - '47494638396101000100800000FFFFFF' - . '00000021F90401000000002C00000000' - . '010001000002024401003B' ); -} - -=head2 PutImage - - PutImage({ biblionumber => $biblionumber, itemnumber => $itemnumber, src_image => $srcimage, replace => $replace }); - -Stores binary image data and thumbnail in database, optionally replacing existing images for the given biblio or item. - -=cut - -sub PutImage { - my ( $params ) = @_; - - my $biblionumber = $params->{biblionumber}; - my $itemnumber = $params->{itemnumber}; - my $srcimage = $params->{src_image}; - my $replace = $params->{replace}; - - Koha::Exceptions::WrongParameter->throw( - 'PutImage cannot be called with both biblionumber and itemnumber') - if $biblionumber and $itemnumber; - - Koha::Exceptions::WrongParameter->throw( - 'PutImage must be called with "replace" if itemnumber is passed. Only 1 cover per item is allowed.') - if $itemnumber and not $replace; - - - return -1 unless defined($srcimage); - - if ($biblionumber && $replace) { - foreach ( ListImagesForBiblio($biblionumber) ) { - DelImage($_); - } - } - - my $dbh = C4::Context->dbh; - my $query = -"INSERT INTO biblioimages (biblionumber, itemnumber, mimetype, imagefile, thumbnail) VALUES (?,?,?,?,?);"; - my $sth = $dbh->prepare($query); - - my $mimetype = 'image/png' - ; # GD autodetects three basic image formats: PNG, JPEG, XPM; we will convert all to PNG which is lossless... - - # Check the pixel size of the image we are about to import... - my $thumbnail = _scale_image( $srcimage, 140, 200 ) - ; # MAX pixel dims are 140 X 200 for thumbnail... - my $fullsize = _scale_image( $srcimage, 600, 800 ) - ; # MAX pixel dims are 600 X 800 for full-size image... - $debug and warn "thumbnail is " . length($thumbnail) . " bytes."; - - $sth->execute( $biblionumber, $itemnumber, $mimetype, $fullsize->png(), - $thumbnail->png() ); - my $dberror = $sth->errstr; - warn sprintf("Error returned inserting %s.%s.", ($biblionumber || $itemnumber, $mimetype)) if $sth->errstr; - undef $thumbnail; - undef $fullsize; - return $dberror; -} - -=head2 RetrieveImage - my ($imagedata, $error) = RetrieveImage($imagenumber); - -Retrieves the specified image. - -=cut - -sub RetrieveImage { - my ($imagenumber) = @_; - - my $dbh = C4::Context->dbh; - my $query = -'SELECT biblionumber, itemnumber, imagenumber, mimetype, imagefile, thumbnail FROM biblioimages WHERE imagenumber = ?'; - my $sth = $dbh->prepare($query); - $sth->execute($imagenumber); - my $imagedata = $sth->fetchrow_hashref; - if ( !$imagedata ) { - $imagedata->{'thumbnail'} = $noimage; - $imagedata->{'imagefile'} = $noimage; - } - if ( $sth->err ) { - warn "Database error!" if $debug; - } - return $imagedata; -} - -=head2 ListImagesForBiblio - my (@images) = ListImagesForBiblio($biblionumber); - -Gets a list of all images associated with a particular biblio. - -=cut - -sub ListImagesForBiblio { - my ($biblionumber) = @_; - - my @imagenumbers; - my $dbh = C4::Context->dbh; - my $query = 'SELECT imagenumber FROM biblioimages WHERE biblionumber = ?'; - my $sth = $dbh->prepare($query); - $sth->execute($biblionumber); - while ( my $row = $sth->fetchrow_hashref ) { - push @imagenumbers, $row->{'imagenumber'}; - } - return @imagenumbers; -} - -=head2 GetImageForItem - my $image = GetImageForItem($itemnumber); - -Gets the image associated with a particular item. - -=cut - -sub GetImageForItem { - my ($itemnumber) = @_; - - my $dbh = C4::Context->dbh; - return $dbh->selectrow_array( - 'SELECT imagenumber FROM biblioimages WHERE itemnumber = ?', - undef, $itemnumber ); -} - -=head2 DelImage - - my ($dberror) = DelImage($imagenumber); - -Removes the image with the supplied imagenumber. - -=cut - -sub DelImage { - my ($imagenumber) = @_; - warn "Imagenumber passed to DelImage is $imagenumber" if $debug; - my $dbh = C4::Context->dbh; - my $query = "DELETE FROM biblioimages WHERE imagenumber = ?;"; - my $sth = $dbh->prepare($query); - $sth->execute($imagenumber); - my $dberror = $sth->errstr; - warn "Database error!" if $sth->errstr; - return $dberror; -} - -sub _scale_image { - my ( $image, $maxwidth, $maxheight ) = @_; - my ( $width, $height ) = $image->getBounds(); - $debug and warn "image is $width pix X $height pix."; - if ( $width > $maxwidth || $height > $maxheight ) { - -# $debug and warn "$filename exceeds the maximum pixel dimensions of $maxwidth X $maxheight. Resizing..."; - my $percent_reduce; # Percent we will reduce the image dimensions by... - if ( $width > $maxwidth ) { - $percent_reduce = - sprintf( "%.5f", ( $maxwidth / $width ) ) - ; # If the width is oversize, scale based on width overage... - } - else { - $percent_reduce = - sprintf( "%.5f", ( $maxheight / $height ) ) - ; # otherwise scale based on height overage. - } - my $width_reduce = sprintf( "%.0f", ( $width * $percent_reduce ) ); - my $height_reduce = sprintf( "%.0f", ( $height * $percent_reduce ) ); - $debug - and warn "Reducing image by " - . ( $percent_reduce * 100 ) - . "\% or to $width_reduce pix X $height_reduce pix"; - my $newimage = GD::Image->new( $width_reduce, $height_reduce, 1 ) - ; #'1' creates true color image... - $newimage->copyResampled( $image, 0, 0, 0, 0, $width_reduce, - $height_reduce, $width, $height ); - return $newimage; - } - else { - return $image; - } -} - -=head2 NoImage - - C4::Images->NoImage; - -Returns the gif to be used when there is no image matching the request, and -its mimetype (image/gif). - -=cut - -sub NoImage { - return $noimage, 'image/gif'; -} - -1; --- a/Koha/Biblio.pm +++ a/Koha/Biblio.pm @@ -779,6 +779,21 @@ sub custom_cover_image_url { return $url; } +=head3 cover_images + +Return the cover images associated with this biblio. + +=cut + +sub cover_images { + my ( $self ) = @_; + + my $cover_images_rs = $self->_result->cover_images; + return unless $cover_images_rs; + return Koha::CoverImages->_new_from_dbic($cover_images_rs); +} + + =head3 to_api my $json = $biblio->to_api; --- a/Koha/CoverImage.pm +++ a/Koha/CoverImage.pm @@ -0,0 +1,116 @@ +package Koha::CoverImage; + +# 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 GD; + +use Koha::Database; + +use base qw(Koha::Object); + +=head1 NAME + +Koha::CoverImage - Koha CoverImage Object class + +=head1 API + +=head2 Class methods + +=head3 new + +my $cover_image = Koha::CoverImage->new( + { + biblionumber => $biblionumber, + itemnumber => $itemnumber, + src_image => $image, + mimetype => $mimetype, + } +); + +biblionumber and/or itemnumber must be passed, otherwise the image will not be +linked to anything. + +src_image must contain the GD image, the fullsize and thumbnail images will be generated +and stored in the database. + +=cut + +sub new { + my ( $class, $params ) = @_; + + my $src_image = delete $params->{src_image}; + + if ( $src_image ) { + ; # GD autodetects three basic image formats: PNG, JPEG, XPM; we will convert all to PNG which is lossless... + + # Check the pixel size of the image we are about to import... + my $thumbnail = $class->_scale_image( $src_image, 140, 200 ) + ; # MAX pixel dims are 140 X 200 for thumbnail... + my $fullsize = $class->_scale_image( $src_image, 600, 800 ) + ; # MAX pixel dims are 600 X 800 for full-size image... + + $params->{mimetype} = 'image/png'; + $params->{imagefile} = $fullsize->png(); + $params->{thumbnail} = $thumbnail->png(); + } + + return $class->SUPER::new($params); +} + +sub _scale_image { + my ( $self, $image, $maxwidth, $maxheight ) = @_; + my ( $width, $height ) = $image->getBounds(); + if ( $width > $maxwidth || $height > $maxheight ) { + + my $percent_reduce; # Percent we will reduce the image dimensions by... + if ( $width > $maxwidth ) { + $percent_reduce = + sprintf( "%.5f", ( $maxwidth / $width ) ) + ; # If the width is oversize, scale based on width overage... + } + else { + $percent_reduce = + sprintf( "%.5f", ( $maxheight / $height ) ) + ; # otherwise scale based on height overage. + } + my $width_reduce = sprintf( "%.0f", ( $width * $percent_reduce ) ); + my $height_reduce = sprintf( "%.0f", ( $height * $percent_reduce ) ); + my $newimage = GD::Image->new( $width_reduce, $height_reduce, 1 ) + ; #'1' creates true color image... + $newimage->copyResampled( $image, 0, 0, 0, 0, $width_reduce, + $height_reduce, $width, $height ); + return $newimage; + } + else { + return $image; + } +} + + +=head2 Internal methods + +=head3 _type + +=cut + +sub _type { + return 'CoverImage'; +} + +1; --- a/Koha/CoverImages.pm +++ a/Koha/CoverImages.pm @@ -0,0 +1,71 @@ +package Koha::CoverImages; + +# 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::CoverImage; + +use base qw(Koha::Objects); + +=head1 NAME + +Koha::Cities - Koha CoverImage Object set class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 no_image + +Returns the gif to be used when there is no image. +Its mimetype is image/gif. + +=cut + +sub no_image { + my $no_image = pack( "H*", + '47494638396101000100800000FFFFFF' + . '00000021F90401000000002C00000000' + . '010001000002024401003B' ); + return Koha::CoverImage->new( + { + mimetype => 'image/gif', + imagefile => $no_image, + thumbnail => $no_image, + } + ); +} + +=head3 _type + +=cut + +sub _type { + return 'CoverImage'; +} + +sub object_class { + return 'Koha::CoverImage'; +} + +1; --- a/Koha/Item.pm +++ a/Koha/Item.pm @@ -35,6 +35,7 @@ use C4::Log qw( logaction ); use Koha::Checkouts; use Koha::CirculationRules; +use Koha::CoverImages; use Koha::SearchEngine::Indexer; use Koha::Item::Transfer::Limits; use Koha::Item::Transfers; @@ -782,6 +783,21 @@ sub renewal_branchcode { return $branchcode; } +=head3 cover_image + +Return the cover image associated with this item. + +=cut + +sub cover_image { + my ( $self ) = @_; + + my $cover_image_rs = $self->_result->cover_images; + return unless $cover_image_rs; + # So far we allow only 1 cover image per item + return Koha::CoverImages->_new_from_dbic($cover_image_rs)->next; +} + =head3 _set_found_trigger $self->_set_found_trigger --- a/catalogue/detail.pl +++ a/catalogue/detail.pl @@ -36,13 +36,13 @@ use C4::External::Amazon; use C4::Search; # enabled_staff_search_views use C4::Tags qw(get_tags); use C4::XSLT; -use C4::Images; use Koha::DateUtils; use C4::HTML5Media; use C4::CourseReserves qw(GetItemCourseReservesInfo); use C4::Acquisition qw(GetOrdersByBiblionumber); use Koha::AuthorisedValues; use Koha::Biblios; +use Koha::CoverImages; use Koha::Illrequests; use Koha::Items; use Koha::ItemTypes; @@ -408,8 +408,8 @@ foreach my $item (@items) { } if ( C4::Context->preference("LocalCoverImages") == 1 ) { - $item->{imagenumber} = - C4::Images::GetImageForItem( $item->{itemnumber} ); + my $cover_image = $item_object->cover_image; + $item->{imagenumber} = $cover_image ? $cover_image->imagenumber : undef; } if ($currentbranch and C4::Context->preference('SeparateHoldings')) { @@ -531,8 +531,8 @@ if (C4::Context->preference("FRBRizeEditions")==1) { } if ( C4::Context->preference("LocalCoverImages") == 1 ) { - my @images = ListImagesForBiblio($biblionumber); - $template->{VARS}->{localimages} = \@images; + my $images = $biblio->cover_images; + $template->param( localimages => $biblio->cover_images ); } # HTML5 Media --- a/catalogue/image.pl +++ a/catalogue/image.pl @@ -27,7 +27,9 @@ use Modern::Perl; use CGI qw ( -utf8 ); #qw(:standard escapeHTML); use C4::Context; -use C4::Images; +use Koha::CoverImages; +use Koha::Biblios; +use Koha::Exceptions; $| = 1; @@ -57,43 +59,38 @@ imagenumber, a random image is selected. =cut -my ( $image, $mimetype ) = C4::Images->NoImage; +my ( $image ); if ( C4::Context->preference("LocalCoverImages") ) { - if ( defined $data->param('imagenumber') ) { + my $imagenumber = $data->param('imagenumber'); + my $biblionumber = $data->param('biblionumber'); + if ( defined $imagenumber ) { $imagenumber = $data->param('imagenumber'); + $image = Koha::CoverImages->find($imagenumber); } - elsif ( defined $data->param('biblionumber') ) { - my @imagenumbers = ListImagesForBiblio( $data->multi_param('biblionumber') ); - if (@imagenumbers) { - $imagenumber = $imagenumbers[0]; - } - else { + elsif ( defined $biblionumber ) { + my $biblio = Koha::Biblios->find($biblionumber); + Koha::Exceptions::ObjectNotFound->throw( 'No bibliographic record for biblionumber ' . $biblionumber ) unless $biblio; + my $cover_images = $biblio->cover_images; + if ( $cover_images->count ) { + $image = $cover_images->next; + } else { warn "No images for this biblio" if $DEBUG; } } - else { - $imagenumber = shift; - } - - if ($imagenumber) { - warn "imagenumber passed in: $imagenumber" if $DEBUG; - my $imagedata = RetrieveImage($imagenumber); - if ($imagedata) { - if ( $data->param('thumbnail') ) { - $image = $imagedata->{'thumbnail'}; - } - else { - $image = $imagedata->{'imagefile'}; - } - $mimetype = $imagedata->{'mimetype'}; - } - } } + +$image ||= Koha::CoverImages->no_image; + +my $image_data = + $data->param('thumbnail') + ? $image->thumbnail + : $image->imagefile; + print $data->header( - -type => $mimetype, + -type => $image->mimetype, -expires => '+30m', - -Content_Length => length($image) -), $image; + -Content_Length => length($image_data) +), $image_data; =head1 AUTHOR --- a/catalogue/imageviewer.pl +++ a/catalogue/imageviewer.pl @@ -24,7 +24,6 @@ use C4::Auth; use C4::Biblio; use C4::Items; use C4::Output; -use C4::Images; use C4::Search; use Koha::Biblios; @@ -68,19 +67,21 @@ if( $query->cookie("searchToOrder") ){ if ( C4::Context->preference("LocalCoverImages") ) { if ( $itemnumber ) { - my $image = C4::Images::GetImageForItem($itemnumber); + my $item = Koha::Items->find($itemnumber); + my $image = $item->cover_image; $template->param( LocalCoverImages => 1, images => [$image], - imagenumber => $imagenumber, + imagenumber => ($image ? $image->imagenumber : undef), ); } else { - my @images = ListImagesForBiblio($biblionumber); + my $images = $biblio->cover_images->as_list; + $template->param( LocalCoverImages => 1, - images => \@images, - imagenumber => $imagenumber || $images[0] || '', + images => $images, + imagenumber => (@$images ? $images->[0]->imagenumber : undef), ); } } --- a/installer/data/mysql/kohastructure.sql +++ a/installer/data/mysql/kohastructure.sql @@ -3382,7 +3382,7 @@ CREATE TABLE `cover_images` ( -- local cover images `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- image creation/update time PRIMARY KEY (`imagenumber`), CONSTRAINT `bibliocoverimage_fk1` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `bibliocoverimage_fk2` FOREIGN KEY (`itemnumber`) REFERENCES `item` (`itemnumber`) ON DELETE CASCADE ON UPDATE CASCADE + CONSTRAINT `bibliocoverimage_fk2` FOREIGN KEY (`itemnumber`) REFERENCES `items` (`itemnumber`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt @@ -169,16 +169,14 @@
[% IF ( LocalCoverImages ) %] - [% IF ( localimages.0 ) %] + [% IF localimages.count %] [% FOREACH image IN localimages %] - [% IF image %] -
- - Local cover image - -
Local cover image
-
- [% END %] +
+ + Local cover image + +
Local cover image
+
[% END %] [% END %] [% END %] @@ -248,9 +246,9 @@ [% IF suggestions.count %]
  • Suggestion details
  • [% END %] [% IF ( FRBRizeEditions ) %][% IF ( XISBNS ) %]
  • Editions
  • [% END %][% END %] [% IF ( LocalCoverImages ) %] - [% IF ( localimages || CAN_user_tools_upload_local_cover_images ) %] + [% IF ( localimages.count || CAN_user_tools_upload_local_cover_images ) %]
  • - Images ([% localimages.size() || 0 | html %]) + Images ([% localimages.count || 0 | html %])
  • [% END %] [% END %] @@ -871,14 +869,14 @@ Note that permanent location is a code, and location may be an authval. [% IF ( LocalCoverImages ) %]
    - [% IF ( localimages.0 ) %] + [% IF localimages.count %]

    Click on an image to view it in the image viewer

      [% FOREACH image IN localimages %] [% IF image %] -
    • - - +
    • + + [% IF CAN_user_tools_upload_local_cover_images %] Delete image --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/imageviewer.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/imageviewer.tt @@ -40,7 +40,7 @@

      [% biblio.author | html %]

      [% IF ( LocalCoverImages == 1 ) %] - [% IF ( images.size > 0 ) %] + [% IF images.size %]
      @@ -55,21 +55,19 @@
      --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt +++ a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt @@ -575,7 +575,7 @@
    • [% END %] - [% IF ( OPACLocalCoverImages && localimages.size ) %] + [% IF ( OPACLocalCoverImages && localimages.count ) %]
    • Images
    • [% END %] @@ -1010,13 +1010,11 @@
    [% END # / IF HTML5MediaEnabled %] - [% IF ( OPACLocalCoverImages && localimages.size ) %] + [% IF ( OPACLocalCoverImages && localimages.count ) %]

    Click on an image to view it in the image viewer

    [% FOREACH image IN localimages %] - [% IF image %] - - [% END %] + [% END %]
    [% END # / IF OPACLocalCoverImages && localimages.size %] --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-imageviewer.tt +++ a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-imageviewer.tt @@ -97,21 +97,21 @@
    [% IF OPACLocalCoverImages == 1 %] - + [% END %] [% ELSE %] Unfortunately, images are not enabled for this catalog at this time. [% END %] --- a/opac/opac-detail.pl +++ a/opac/opac-detail.pl @@ -45,7 +45,6 @@ use C4::Letters; use MARC::Record; use MARC::Field; use List::MoreUtils qw/any none/; -use C4::Images; use Koha::DateUtils; use C4::HTML5Media; use C4::CourseReserves qw(GetItemCourseReservesInfo); @@ -764,8 +763,8 @@ if ( not $viewallitems and @items > $max_items_to_display ) { } if ( C4::Context->preference("OPACLocalCoverImages") == 1 ) { - $itm->{imagenumber} = - C4::Images::GetImageForItem( $itm->{itemnumber} ); + my $cover_image = $item->cover_image; + $itm->{imagenumber} = $cover_image ? $cover_image->imagenumber : undef; } my $itembranch = $itm->{$separatebranch}; @@ -1248,8 +1247,7 @@ my $defaulttab = $template->param('defaulttab' => $defaulttab); if (C4::Context->preference('OPACLocalCoverImages') == 1) { - my @images = ListImagesForBiblio($biblionumber); - $template->{VARS}->{localimages} = \@images; + $template->param( localimages => $biblio->cover_images ); } $template->{VARS}->{OPACPopupAuthorsSearch} = C4::Context->preference('OPACPopupAuthorsSearch'); --- a/opac/opac-image.pl +++ a/opac/opac-image.pl @@ -27,7 +27,8 @@ use Modern::Perl; use CGI qw ( -utf8 ); use C4::Context; -use C4::Images; +use Koha::Biblios; +use Koha::CoverImages; $| = 1; @@ -57,43 +58,38 @@ imagenumber, a random image is selected. =cut -my ( $image, $mimetype ) = C4::Images->NoImage; +my ( $image ); if ( C4::Context->preference("OPACLocalCoverImages") ) { - if ( defined $data->param('imagenumber') ) { + my $imagenumber = $data->param('imagenumber'); + my $biblionumber = $data->param('biblionumber'); + if ( defined $imagenumber ) { $imagenumber = $data->param('imagenumber'); + $image = Koha::CoverImages->find($imagenumber); } - elsif ( defined $data->param('biblionumber') ) { - my @imagenumbers = ListImagesForBiblio( scalar $data->param('biblionumber') ); - if (@imagenumbers) { - $imagenumber = $imagenumbers[0]; - } - else { + elsif ( defined $biblionumber ) { + my $biblio = Koha::Biblios->find($biblionumber); + Koha::Exceptions::ObjectNotFound->throw( 'No bibliographic record for biblionumber ' . $biblionumber ) unless $biblio; + my $cover_images = $biblio->cover_images; + if ( $cover_images->count ) { + $image = $cover_images->next; + } else { warn "No images for this biblio" if $DEBUG; } } - else { - $imagenumber = shift; - } - - if ($imagenumber) { - warn "imagenumber passed in: $imagenumber" if $DEBUG; - my $imagedata = RetrieveImage($imagenumber); - if ($imagedata) { - if ( $data->param('thumbnail') ) { - $image = $imagedata->{'thumbnail'}; - } - else { - $image = $imagedata->{'imagefile'}; - } - $mimetype = $imagedata->{'mimetype'}; - } - } } + +$image ||= Koha::CoverImages->no_image; + +my $image_data = + $data->param('thumbnail') + ? $image->thumbnail + : $image->imagefile; + print $data->header( - -type => $mimetype, + -type => $image->mimetype, -expires => '+30m', - -Content_Length => length($image) -), $image; + -Content_Length => length($image_data) +), $image_data; =head1 AUTHOR --- a/opac/opac-imageviewer.pl +++ a/opac/opac-imageviewer.pl @@ -23,9 +23,9 @@ use CGI qw ( -utf8 ); use C4::Auth; use C4::Biblio; use C4::Output; -use C4::Images; use Koha::Biblios; +use Koha::CoverImages; use Koha::Items; my $query = new CGI; @@ -42,19 +42,19 @@ my $biblionumber = $query->param('biblionumber') || $query->param('bib'); my $imagenumber = $query->param('imagenumber'); unless ( $biblionumber ) { # Retrieving the biblio from the imagenumber - my $image = C4::Images::RetrieveImage($imagenumber); + my $image = Koha::CoverImages->find($imagenumber); my $item = Koha::Items->find($image->{itemnumber}); $biblionumber = $item->biblionumber; } my $biblio = Koha::Biblios->find( $biblionumber ); if ( C4::Context->preference("OPACLocalCoverImages") ) { - my @images = !$imagenumber ? ListImagesForBiblio($biblionumber) : (); + my $images = !$imagenumber ? Koha::Biblios->find($biblionumber)->cover_images->as_list : []; $template->param( OPACLocalCoverImages => 1, - images => \@images, + images => $images, biblionumber => $biblionumber, - imagenumber => $imagenumber || $images[0] || '', + imagenumber => (@$images ? $images->[0]->imagenumber : $imagenumber), ); } --- a/svc/cover_images +++ a/svc/cover_images @@ -22,7 +22,7 @@ use Modern::Perl; use CGI qw ( -utf8 ); use C4::Auth qw/check_cookie_auth/; -use C4::Images; +use Koha::CoverImages; use JSON qw/to_json/; my $input = new CGI; @@ -46,7 +46,7 @@ if ( $action eq "delete" ) { foreach my $imagenumber ( @imagenumbers ) { eval { - DelImage($imagenumber); + Koha::CoverImages->find($imagenumber)->delete; }; if ( $@ ) { push @$response, { --- a/t/Images.t +++ a/t/Images.t @@ -1,71 +0,0 @@ -#!/usr/bin/perl - -# 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 Test::More; -use Test::MockModule; - -use Module::Load::Conditional qw/check_install/; - -BEGIN { - if ( check_install( module => 'Test::DBIx::Class' ) ) { - plan tests => 8; - } else { - plan skip_all => "Need Test::DBIx::Class" - } -} - -use_ok('C4::Images'); - -use Test::DBIx::Class; - -# Make the code in the module use our mocked Koha::Schema/Koha::Database -my $db = Test::MockModule->new('Koha::Database'); -$db->mock( - # Schema() gives us the DB connection set up by Test::DBIx::Class - _new_schema => sub { return Schema(); } -); - -my $biblionumber = 2; -my $images = [ - [ 1, $biblionumber, 'gif', 'imagefile1', 'thumbnail1' ], - [ 3, $biblionumber, 'jpeg', 'imagefile3', 'thumbnail3' ], -]; -fixtures_ok [ - Biblioimage => [ - [ 'imagenumber', 'biblionumber', 'mimetype', 'imagefile', 'thumbnail' ], - @$images, - ], -], 'add fixtures'; - -my $image = C4::Images::RetrieveImage(1); - -is( $image->{'imagenumber'}, 1, 'First imagenumber is 1' ); - -is( $image->{'mimetype'}, 'gif', 'First mimetype is gif' ); - -is( $image->{'thumbnail'}, 'thumbnail1', 'First thumbnail is correct' ); - -my @imagenumbers = C4::Images::ListImagesForBiblio($biblionumber); - -is( $imagenumbers[0], 1, 'imagenumber is 1' ); - -is( $imagenumbers[1], 3, 'imagenumber is 3' ); - -is( $imagenumbers[4], undef, 'imagenumber undef' ); - --- a/t/db_dependent/Koha/CoverImages.t +++ a/t/db_dependent/Koha/CoverImages.t @@ -81,16 +81,13 @@ is( ref( $item->cover_image ), 'Koha::CoverImage', 'Koha::Item->cover_image returns a Koha::CoverImage object' ); -throws_ok { - Koha::CoverImage->new( - { - biblionumber => $biblio->biblionumber, - itemnumber => $item->itemnumber, - src_image => GD::Image->new($logo_filepath) - } - )->store -} -'Koha::Exceptions::WrongParameter', - 'Exception is thrown if both biblionumber and itemnumber are passed'; +Koha::CoverImage->new( + { + biblionumber => $biblio->biblionumber, + itemnumber => $item->itemnumber, + src_image => GD::Image->new($logo_filepath) + } +)->store; +is( $biblio->cover_images->count, 3, ); $schema->storage->txn_rollback; --- a/tools/upload-cover-image.pl +++ a/tools/upload-cover-image.pl @@ -45,7 +45,8 @@ use GD; use C4::Context; use C4::Auth; use C4::Output; -use C4::Images; +use Koha::Biblios; +use Koha::CoverImages; use Koha::Items; use Koha::UploadedFiles; use C4::Log; @@ -92,8 +93,25 @@ if ($fileID) { my $srcimage = GD::Image->new($fh); $fh->close if $fh; if ( defined $srcimage ) { - my $dberror = PutImage( { biblionumber => $biblionumber, itemnumber => $itemnumber, src_image => $srcimage, replace => $replace } ); - if ($dberror) { + eval { + if ( $replace && $biblionumber ) { + Koha::Biblios->find($biblionumber)->cover_images->delete; + } elsif ( $itemnumber ) { + my $cover_image = Koha::Items->find($itemnumber)->cover_image; + $cover_image->delete if $cover_image; + } + + Koha::CoverImage->new( + { + biblionumber => $biblionumber, + itemnumber => $itemnumber, + src_image => $srcimage + } + )->store; + }; + + if ($@) { + warn $@; $error = 'DBERR'; } else { @@ -162,14 +180,23 @@ if ($fileID) { my $srcimage = GD::Image->new("$dir/$filename"); if ( defined $srcimage ) { $total++; - my $dberror = PutImage( - { - biblionumber => $biblionumber, - src_image => $srcimage, - replace => $replace + eval { + if ( $replace && $biblionumber ) { + Koha::Biblios->find($biblionumber)->cover_images->delete; + } elsif ( $itemnumber ) { + Koha::Items->find($itemnumber)->cover_image->delete; } - ); - if ($dberror) { + + Koha::CoverImage->new( + { + biblionumber => $biblionumber, + itemnumber => $itemnumber, + src_image => $srcimage + } + )->store; + }; + + if ($@) { $error = 'DBERR'; } } --