Bugzilla – Attachment 110348 Details for
Bug 26145
Add the ability to attach a cover image at item level
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 26145: Allow multi covers per item
Bug-26145-Allow-multi-covers-per-item.patch (text/plain), 23.07 KB, created by
Jonathan Druart
on 2020-09-18 10:23:15 UTC
(
hide
)
Description:
Bug 26145: Allow multi covers per item
Filename:
MIME Type:
Creator:
Jonathan Druart
Created:
2020-09-18 10:23:15 UTC
Size:
23.07 KB
patch
obsolete
>From 30c9300f8adcd0df814c416a7b501e4dde368895 Mon Sep 17 00:00:00 2001 >From: Jonathan Druart <jonathan.druart@bugs.koha-community.org> >Date: Tue, 11 Aug 2020 18:26:01 +0200 >Subject: [PATCH] Bug 26145: Allow multi covers per item > >In this patch we remove the limitation of 1 cover image per item > >Sponsored-by: Gerhard Sondermann Dialog e.K. (presseplus.de, presseshop.at, presseshop.ch) >--- > Koha/Item.pm | 9 +- > catalogue/detail.pl | 9 +- > catalogue/imageviewer.pl | 23 ++- > .../prog/css/src/staff-global.scss | 9 +- > .../admin/preferences/enhanced_content.pref | 2 +- > .../prog/en/modules/catalogue/detail.tt | 151 ++++++++++-------- > .../prog/en/modules/tools/upload-images.tt | 2 +- > .../bootstrap/en/modules/opac-detail.tt | 4 +- > opac/opac-detail.pl | 9 +- > t/db_dependent/Koha/CoverImages.t | 9 +- > tools/upload-cover-image.pl | 21 +-- > 11 files changed, 130 insertions(+), 118 deletions(-) > >diff --git a/Koha/Item.pm b/Koha/Item.pm >index a7d3f78771..f1d985176f 100644 >--- a/Koha/Item.pm >+++ b/Koha/Item.pm >@@ -785,19 +785,18 @@ sub renewal_branchcode { > return $branchcode; > } > >-=head3 cover_image >+=head3 cover_images > >-Return the cover image associated with this item. >+Return the cover images associated with this item. > > =cut > >-sub cover_image { >+sub cover_images { > 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; >+ return Koha::CoverImages->_new_from_dbic($cover_image_rs); > } > > =head3 _set_found_trigger >diff --git a/catalogue/detail.pl b/catalogue/detail.pl >index 4e6404398e..7b7f4d2944 100755 >--- a/catalogue/detail.pl >+++ b/catalogue/detail.pl >@@ -408,21 +408,20 @@ foreach my $item (@items) { > } > > if ( C4::Context->preference("LocalCoverImages") == 1 ) { >- my $cover_image = $item_object->cover_image; >- $item->{imagenumber} = $cover_image ? $cover_image->imagenumber : undef; >+ $item->{cover_images} = $item_object->cover_images; > } > > if ($currentbranch and C4::Context->preference('SeparateHoldings')) { > if ($itembranchcode and $itembranchcode eq $currentbranch) { > push @itemloop, $item; >- $itemloop_has_images++ if $item->{imagenumber}; >+ $itemloop_has_images++ if $item_object->cover_images->count; > } else { > push @otheritemloop, $item; >- $otheritemloop_has_images++ if $item->{imagenumber}; >+ $otheritemloop_has_images++ if $item_object->cover_images->count; > } > } else { > push @itemloop, $item; >- $itemloop_has_images++ if $item->{imagenumber}; >+ $itemloop_has_images++ if $item_object->cover_images->count; > } > } > >diff --git a/catalogue/imageviewer.pl b/catalogue/imageviewer.pl >index 3ed64fe8cc..b71a3c2e75 100755 >--- a/catalogue/imageviewer.pl >+++ b/catalogue/imageviewer.pl >@@ -66,24 +66,19 @@ if( $query->cookie("searchToOrder") ){ > } > > if ( C4::Context->preference("LocalCoverImages") ) { >+ my $images; > if ( $itemnumber ) { > my $item = Koha::Items->find($itemnumber); >- my $image = $item->cover_image; >- $template->param( >- LocalCoverImages => 1, >- images => [$image], >- imagenumber => ($image ? $image->imagenumber : undef), >- ); >- >+ $images = $item->cover_images->as_list; > } else { >- my $images = $biblio->cover_images->as_list; >- >- $template->param( >- LocalCoverImages => 1, >- images => $images, >- imagenumber => (@$images ? $images->[0]->imagenumber : undef), >- ); >+ $images = $biblio->cover_images->as_list; > } >+ >+ $template->param( >+ LocalCoverImages => 1, >+ images => $images, >+ imagenumber => (@$images ? $images->[0]->imagenumber : undef), >+ ); > } > $template->{VARS}->{'count'} = $itemcount; > $template->{VARS}->{'biblionumber'} = $biblionumber; >diff --git a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >index 9a7470546e..d313d9aeb9 100644 >--- a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >+++ b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >@@ -2117,7 +2117,7 @@ li { > display: inline-block; > } > >-#bookcoverimg { >+.bookcoverimg { > text-align: center; > } > >@@ -2127,13 +2127,16 @@ li { > } > } > >-.cover-slides { >- background: #FFF url("[% interface | html %]/[% theme | html %]/img/spinner-small.gif") center center no-repeat; >+#biblio-cover-slider { > border: 1px solid #b9d8d9; > border-radius: 3px; > margin: 5px; > padding: 10px 5px 5px 5px; > min-height: 175px; >+} >+ >+.cover-slides { >+ background: #FFF url("[% interface | html %]/[% theme | html %]/img/spinner-small.gif") center center no-repeat; > > .hint { > font-size: 90%; >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref >index 7e7cdfaaa7..abd8269440 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref >@@ -316,7 +316,7 @@ Enhanced content: > choices: > yes: Allow > no: "Don't allow" >- - multiple images to be attached to each bibliographic record. >+ - multiple images to be attached to each bibliographic record and item. > - > - pref: CustomCoverImages > choices: >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >index a0fd66876d..6e0d1f78a8 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >@@ -166,8 +166,8 @@ > > [% IF ( AmazonCoverImages || LocalCoverImages || AdlibrisEnabled || IntranetCoce || (Koha.Preference('CustomCoverImages') && Koha.Preference('CustomCoverImagesURL')) ) %] > </div> >- <div class="col-xs-3" id="bookcoverimg"> >- <div id="cover-slides"> >+ <div class="col-xs-3 bookcoverimg"> >+ <div id="biblio-cover-slider" class="cover-slider"> > [% IF ( LocalCoverImages ) %] > [% IF localimages.count %] > [% FOREACH image IN localimages %] >@@ -219,8 +219,8 @@ > <div class="hint">Custom cover image</div> > </div> > [% END %] >- </div> <!-- /#cover-slides --> >- </div> <!-- /#bookcoverimg.col-xs-3 --> >+ </div> <!-- /.cover-slider --> >+ </div> <!-- /.bookcoverimg.col-xs-3 --> > [% ELSE %] > </div> <!-- /.col-xs-* --> > [% END # /IF ( AmazonCoverImages, etc ) %] >@@ -326,11 +326,17 @@ > [% END %] > [% IF ( tab == 'holdings' && itemloop_has_images || tab == 'otherholdings' && otheritemloop_has_images ) %] > <td class="cover"> >- [% IF item.imagenumber %] >- <a href="/cgi-bin/koha/catalogue/imageviewer.pl?itemnumber=[% item.itemnumber | uri %]&imagenumber=[% item.imagenumber | uri %]"> >- <img src="/cgi-bin/koha/catalogue/image.pl?thumbnail=1amp;imagenumber=[% item.imagenumber | uri %]" /> >- </a> >- [% END %] >+ <div class="bookcoverimg"> >+ <div class="cover-slider"> >+ [% FOREACH image IN item.cover_images %] >+ <div class="cover-image local-coverimg"> >+ <a href="/cgi-bin/koha/catalogue/imageviewer.pl?itemnumber=[% image.itemnumber | uri %]&imagenumber=[% image.imagenumber | uri %]"> >+ <img src="/cgi-bin/koha/catalogue/image.pl?thumbnail=1&imagenumber=[% image.imagenumber | uri %]" alt="Local cover image" /> >+ </a> >+ </div> >+ [% END %] >+ </div> >+ </div> > </td> > [% END %] > >@@ -986,71 +992,75 @@ Note that permanent location is a code, and location may be an authval. > // http://www.oreillynet.com/pub/a/javascript/2003/10/21/amazonhacks.html > function verify_images() { > // Loop over each container in the template which contains covers >- $(".cover-image").each( function( index ){ >- var div = $(this); >- // Find the image in the container >- var img = div.find("img")[0]; >- if( $(img).length > 0 ){ >- if( (img.complete != null) && (!img.complete) || img.naturalHeight == 0 ){ >- // No image loaded in the container. Remove the slide >- div.remove(); >- } else { >- // All slides start hidden. If this is the first one, show it. >- if( index == 0 ){ >- div.show(); >- } >- // Check if Amazon image is present >- if ( div.attr("id") == "amazon-bookcoverimg" ) { >- w = img.width; >- h = img.height; >- if ((w == 1) || (h == 1)) { >- // Amazon returned single-pixel placeholder >- // Remove the container >- div.remove(); >+ $(".cover-slider").each(function(){ >+ $(this).find(".cover-image").each( function( index ){ >+ var div = $(this); >+ // Find the image in the container >+ var img = div.find("img")[0]; >+ if( $(img).length > 0 ){ >+ if( (img.complete != null) && (!img.complete) || img.naturalHeight == 0 ){ >+ // No image loaded in the container. Remove the slide >+ div.remove(); >+ } else { >+ // All slides start hidden. If this is the first one, show it. >+ if( index == 0 ){ >+ div.show(); > } >- } >- if( div.attr("id") == "custom-img" ){ >- if ( (img.complete != null) && (!img.complete) || img.naturalHeight == 0 ) { >- // No image was loaded via the CustomCoverImages system preference >- // Remove the container >- div.remove(); >+ // Check if Amazon image is present >+ if ( div.attr("id") == "amazon-bookcoverimg" ) { >+ w = img.width; >+ h = img.height; >+ if ((w == 1) || (h == 1)) { >+ // Amazon returned single-pixel placeholder >+ // Remove the container >+ div.remove(); >+ } > } >- } >- if( div.attr("id") == "coce-coverimg" ){ >- // Identify which service's image is being loaded by Coce >- if( $(img).attr("src").indexOf('amazon.com') >= 0 ){ >- div.find(".hint").html(_("Coce image from Amazon.com")); >- } else if( $(img).attr("src").indexOf('google.com') >= 0 ){ >- div.find(".hint").html(_("Coce image from Google Books")); >- } else if( $(img).attr("src").indexOf('openlibrary.org') >= 0 ){ >- div.find(".hint").html(_("Coce image from Open Library")); >+ if( div.attr("id") == "custom-img" ){ >+ if ( (img.complete != null) && (!img.complete) || img.naturalHeight == 0 ) { >+ // No image was loaded via the CustomCoverImages system preference >+ // Remove the container >+ div.remove(); >+ } >+ } >+ if( div.attr("id") == "coce-coverimg" ){ >+ // Identify which service's image is being loaded by Coce >+ if( $(img).attr("src").indexOf('amazon.com') >= 0 ){ >+ div.find(".hint").html(_("Coce image from Amazon.com")); >+ } else if( $(img).attr("src").indexOf('google.com') >= 0 ){ >+ div.find(".hint").html(_("Coce image from Google Books")); >+ } else if( $(img).attr("src").indexOf('openlibrary.org') >= 0 ){ >+ div.find(".hint").html(_("Coce image from Open Library")); >+ } > } > } > } >- } >+ }); > }); > >- var coverSlides = $(".cover-image"); >- if( coverSlides.length > 1 ){ >- coverSlides.each(function( index ){ >- // If more that one slide is present, add a navigation link >- // for activating the slide >- var covernav = $("<a href=\"#\" data-num=\"" + index + "\" class=\"cover-nav\"></a>"); >- if( index == 0 ){ >- // Set the first navigation link as active >- $(covernav).addClass("nav-active"); >- } >- $(covernav).html("<i class=\"fa fa-circle\"></i>"); >- $("#cover-slides").append( covernav ); >- >- }); >- } >+ $(".cover-slider").each(function(){ >+ var coverSlide = this; >+ var coverImages = $(this).find(".cover-image"); >+ if( coverImages.length > 1 ){ >+ coverImages.each(function( index ){ >+ // If more that one image is present, add a navigation link >+ // for activating the slide >+ var covernav = $("<a href=\"#\" data-num=\"" + index + "\" class=\"cover-nav\"></a>"); >+ if( index == 0 ){ >+ // Set the first navigation link as active >+ $(covernav).addClass("nav-active"); >+ } >+ $(covernav).html("<i class=\"fa fa-circle\"></i>"); >+ $(coverSlide).append( covernav ); >+ }); >+ } > >- if( $(".cover-image:visible").length < 1 ){ >- $("#cover-slides").remove(); >- } else { >- $("#cover-slides").addClass("cover-slides"); >- } >+ if( $(coverSlide).find(".cover-image:visible").length < 1 ){ >+ $(coverSlide).remove(); >+ } else { >+ $(coverSlide).addClass("cover-slides"); >+ } >+ }); > > $("#editions img").each(function(i){ > if ( this.src.indexOf('amazon.com') >= 0 ) { >@@ -1223,14 +1233,15 @@ Note that permanent location is a code, and location may be an authval. > link = $(this).attr("href"); > openWindow(link,"Print spine label",400,400); > }); >- $("#cover-slides").on("click",".cover-nav", function(e){ >+ $(".cover-slider").on("click",".cover-nav", function(e){ > e.preventDefault(); >+ var cover_slider = $(this).parent(); > // Adding click handler for cover image navigation links > var num = $(this).data("num"); >- $(".cover-nav").removeClass("nav-active"); >+ $(cover_slider).find(".cover-nav").removeClass("nav-active"); > $(this).addClass("nav-active"); >- $(".cover-image").hide(); >- $(".cover-image").eq( num ).show(); >+ $(cover_slider).find(".cover-image").hide(); >+ $(cover_slider).find(".cover-image").eq( num ).show(); > }); > }); > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt >index 9abce8f7ec..9ebb48e462 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt >@@ -100,7 +100,7 @@ > <legend>Options</legend> > <ol> > <li class="checkbox"> >- [% IF AllowMultipleCovers == 0 OR itemnumber%] >+ [% IF AllowMultipleCovers == 0 %] > <input type="checkbox" id="replace" name="replace" checked="checked" disabled="disabled" value="1" /> > [% ELSE %] > <input type="checkbox" id="replace" name="replace" value="1" /> >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt >index 8e531bafcc..1c3cbf464c 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt >@@ -1267,7 +1267,9 @@ > > [% IF ( tab == 'holdings' && itemloop_has_images || tab == 'otherholdings' && otheritemloop_has_images ) %] > <td class="cover"> >- <div title="[% ITEM_RESULT.itemnumber | html %]" data-imagenumber="[% ITEM_RESULT.imagenumber | html %]" data-biblionumber="[% ITEM_RESULT.biblionumber %]" class="local-thumbnail-preview"></div> >+ [% FOR image IN ITEM_RESULT.cover_images %] >+ <div title="[% ITEM_RESULT.itemnumber | html %]" data-imagenumber="[% image.imagenumber | html %]" data-biblionumber="[% ITEM_RESULT.biblionumber | html %]" class="local-thumbnail-preview"></div> >+ [% END %] > </td> > [% END %] > >diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl >index 67c074cd70..8b935af155 100755 >--- a/opac/opac-detail.pl >+++ b/opac/opac-detail.pl >@@ -763,22 +763,21 @@ if ( not $viewallitems and @items > $max_items_to_display ) { > } > > if ( C4::Context->preference("OPACLocalCoverImages") == 1 ) { >- my $cover_image = $item->cover_image; >- $itm->{imagenumber} = $cover_image ? $cover_image->imagenumber : undef; >+ $itm->{cover_images} = $item->cover_images; > } > > my $itembranch = $itm->{$separatebranch}; > if ($currentbranch and C4::Context->preference('OpacSeparateHoldings')) { > if ($itembranch and $itembranch eq $currentbranch) { > push @itemloop, $itm; >- $itemloop_has_images++ if $itm->{imagenumber}; >+ $itemloop_has_images++ if $item->cover_images->count; > } else { > push @otheritemloop, $itm; >- $otheritemloop_has_images++ if $itm->{imagenumber}; >+ $otheritemloop_has_images++ if $item->cover_images->count; > } > } else { > push @itemloop, $itm; >- $itemloop_has_images++ if $itm->{imagenumber}; >+ $itemloop_has_images++ if $item->cover_images->count; > } > } > } >diff --git a/t/db_dependent/Koha/CoverImages.t b/t/db_dependent/Koha/CoverImages.t >index 66067df9b7..ff4c12ed54 100644 >--- a/t/db_dependent/Koha/CoverImages.t >+++ b/t/db_dependent/Koha/CoverImages.t >@@ -19,7 +19,7 @@ > > use Modern::Perl; > >-use Test::More tests => 13; >+use Test::More tests => 14; > use Test::Exception; > > use FindBin '$Bin'; >@@ -70,16 +70,16 @@ $image = Koha::CoverImage->new( > )->store; > is( $biblio->cover_images->count, 2, 'There are now two cover images' ); > >-is( $item->cover_image, undef, 'No cover images yet' ); >+is( $item->cover_images->count, 0, 'No cover images yet' ); > $image = Koha::CoverImage->new( > { > itemnumber => $item->itemnumber, > src_image => GD::Image->new($logo_filepath) > } > )->store; >-is( ref( $item->cover_image ), >+is( ref( $item->cover_images->next ), > 'Koha::CoverImage', >- 'Koha::Item->cover_image returns a Koha::CoverImage object' ); >+ 'Koha::Item->cover_images returns a rs of Koha::CoverImage object' ); > > Koha::CoverImage->new( > { >@@ -89,5 +89,6 @@ Koha::CoverImage->new( > } > )->store; > is( $biblio->cover_images->count, 3, ); >+is( $item->cover_images->count, 2, ); > > $schema->storage->txn_rollback; >diff --git a/tools/upload-cover-image.pl b/tools/upload-cover-image.pl >index 85cbedc465..6c19de1e99 100755 >--- a/tools/upload-cover-image.pl >+++ b/tools/upload-cover-image.pl >@@ -94,11 +94,12 @@ if ($fileID) { > $fh->close if $fh; > if ( defined $srcimage ) { > 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; >+ if ( $replace ) { >+ if ( $biblionumber ) { >+ Koha::Biblios->find($biblionumber)->cover_images->delete; >+ } elsif ( $itemnumber ) { >+ Koha::Items->find($itemnumber)->cover_images->delete; >+ } > } > > Koha::CoverImage->new( >@@ -181,10 +182,12 @@ if ($fileID) { > if ( defined $srcimage ) { > $total++; > eval { >- if ( $replace && $biblionumber ) { >- Koha::Biblios->find($biblionumber)->cover_images->delete; >- } elsif ( $itemnumber ) { >- Koha::Items->find($itemnumber)->cover_image->delete; >+ if ( $replace ) { >+ if ( $biblionumber ) { >+ Koha::Biblios->find($biblionumber)->cover_images->delete; >+ } elsif ( $itemnumber ) { >+ Koha::Items->find($itemnumber)->cover_images->delete; >+ } > } > > Koha::CoverImage->new( >-- >2.20.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 26145
:
109225
|
109226
|
110342
|
110343
|
110344
|
110345
|
110346
|
110347
|
110348
|
110349
|
110350
|
110351
|
110352
|
110353
|
110354
|
110675
|
110676
|
110677
|
110678
|
110679
|
110680
|
110681
|
110682
|
110683
|
110684
|
110685
|
110800
|
110861
|
110862
|
110863
|
110864
|
110865
|
110866
|
110867
|
110868
|
110869
|
110870
|
110871
|
110872
|
110873
|
110874
|
110875
|
111446
|
111447
|
111448
|
111449
|
111450
|
111451
|
111452
|
111453
|
111454
|
111455
|
111456
|
111457
|
111458