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) Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de> Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
This commit is contained in:
parent
7bc87ce75e
commit
a06223a20d
|
|
@ -782,19 +782,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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -2115,7 +2115,7 @@ li {
|
|||
display: inline-block;
|
||||
}
|
||||
|
||||
#bookcoverimg {
|
||||
.bookcoverimg {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
|
@ -2125,13 +2125,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%;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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 %]
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Reference in New Issue