Browse Source

Bug 10856: Improve the previous and next items on the shelf browser

The next and previous links should completely refresh the shelf.

For example:
[<] [1] [2] [3] [4] [5] [6] [>]
Before this patch, the next and previous links were the same as the 1
and 6.
With this patch, after clicking on next, we will get:
[<] [7] [8] [9] [10] [11] [12] [13] [>]

This patch adds a new AJAX script to get the shelf browser block.

Test plan:
- On a detail biblio page, click on a "Browse shelf" link.
- Play with the next and previous links.
- Deactivate Javascript (using NoScript for example) and check that you
  get the same behavior (but the page is reloaded).
- Launch the unit tests: prove t/db_dependent/ShelfBrowser.t

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Katrin Fischer <Katrin.Fischer.83@web.de>
Passes all tests and QA script.

Signed-off-by: Galen Charlton <gmc@esilibrary.com>
new/bootstrap-opac
Jonathan Druart 11 years ago
committed by Galen Charlton
parent
commit
5c0fa5ec3d
  1. 125
      C4/ShelfBrowser.pm
  2. 125
      koha-tmpl/opac-tmpl/prog/en/includes/shelfbrowser.inc
  3. 135
      koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt
  4. 2
      koha-tmpl/opac-tmpl/prog/en/modules/svc/shelfbrowser.tt
  5. 12
      opac/opac-detail.pl
  6. 41
      opac/svc/shelfbrowser.pl
  7. 212
      t/db_dependent/ShelfBrowser.t

125
C4/ShelfBrowser.pm

@ -63,10 +63,9 @@ to take into account.
$nearby = GetNearbyItems($itemnumber, [$num_each_side]);
@next = @{ $nearby->{next} };
@prev = @{ $nearby->{prev} };
@items = @{ $nearby->{items} };
foreach (@next) {
foreach (@items) {
# These won't format well like this, but here are the fields
print $_->{title};
print $_->{biblionumber};
@ -78,10 +77,10 @@ to take into account.
# This is the information required to scroll the browser to the next left
# or right set. Can be derived from next/prev, but it's here for convenience.
print $nearby->{prev_itemnumber};
print $nearby->{next_itemnumber};
print $nearby->{prev_biblionumber};
print $nearby->{next_biblionumber};
print $nearby->{prev_item}{itemnumber};
print $nearby->{next_item}{itemnumber};
print $nearby->{prev_item}{biblionumber};
print $nearby->{next_item}{biblionumber};
# These will be undef if the values are not used to calculate the
# nearby items.
@ -92,8 +91,6 @@ to take into account.
print $nearby->{starting_ccode}->{code};
print $nearby->{starting_ccode}->{description};
print $nearby->{starting_itemnumber};
This finds the items that are nearby to the supplied item, and supplies
those previous and next, along with the other useful information for displaying
the shelf browser.
@ -113,11 +110,13 @@ This will throw an exception if something went wrong.
=cut
sub GetNearbyItems {
my ($itemnumber, $num_each_side) = @_;
my ( $itemnumber, $num_each_side, $gap) = @_;
$num_each_side ||= 3;
$gap ||= 7; # Should be > $num_each_side
die "BAD CALL in C4::ShelfBrowser::GetNearbyItems, gap should be > num_each_side"
if $gap <= $num_each_side;
my $dbh = C4::Context->dbh;
my $marcflavour = C4::Context->preference("marcflavour");
my $branches = GetBranches();
my $sth_get_item_details = $dbh->prepare("SELECT cn_sort,homebranch,location,ccode from items where itemnumber=?");
@ -145,12 +144,12 @@ sub GetNearbyItems {
# Build the query for previous and next items
my $prev_query ='
SELECT *
SELECT itemnumber, biblionumber, cn_sort, itemcallnumber
FROM items
WHERE
((cn_sort = ? AND itemnumber < ?) OR cn_sort < ?) ';
my $next_query ='
SELECT *
SELECT itemnumber, biblionumber, cn_sort, itemcallnumber
FROM items
WHERE
((cn_sort = ? AND itemnumber >= ?) OR cn_sort > ?) ';
@ -170,60 +169,68 @@ sub GetNearbyItems {
push @params, $start_ccode->{code};
}
my $sth_prev_items = $dbh->prepare($prev_query . $query_cond . ' ORDER BY cn_sort DESC, itemnumber LIMIT ?');
my $sth_next_items = $dbh->prepare($next_query . $query_cond . ' ORDER BY cn_sort, itemnumber LIMIT ?');
push @params, $num_each_side;
$sth_prev_items->execute(@params);
$sth_next_items->execute(@params);
# Now we have the query run, suck out the data like marrow
my @prev_items = reverse GetShelfInfo($sth_prev_items, $marcflavour);
my @next_items = GetShelfInfo($sth_next_items, $marcflavour);
my (
$next_itemnumber, $next_biblionumber,
$prev_itemnumber, $prev_biblionumber
my @prev_items = @{
$dbh->selectall_arrayref(
$prev_query . $query_cond . ' ORDER BY cn_sort DESC, itemnumber LIMIT ?',
{ Slice => {} },
( @params, $gap )
)
};
my @next_items = @{
$dbh->selectall_arrayref(
$next_query . $query_cond . ' ORDER BY cn_sort, itemnumber LIMIT ?',
{ Slice => {} },
( @params, $gap + 1 )
)
};
my $prev_item = $prev_items[-1];
my $next_item = $next_items[-1];
@next_items = splice( @next_items, 0, $num_each_side + 1 );
@prev_items = reverse splice( @prev_items, 0, $num_each_side );
my @items = ( @prev_items, @next_items );
$next_item = undef
if not $next_item
or ( $next_item->{itemnumber} == $items[-1]->{itemnumber}
and ( @prev_items or @next_items <= 1 )
);
$next_itemnumber = $next_items[-1]->{itemnumber} if @next_items;
$next_biblionumber = $next_items[-1]->{biblionumber} if @next_items;
$prev_itemnumber = $prev_items[0]->{itemnumber} if @prev_items;
$prev_biblionumber = $prev_items[0]->{biblionumber} if @prev_items;
my %result = (
next => \@next_items,
prev => \@prev_items,
next_itemnumber => $next_itemnumber,
next_biblionumber => $next_biblionumber,
prev_itemnumber => $prev_itemnumber,
prev_biblionumber => $prev_biblionumber,
starting_itemnumber => $itemnumber,
$prev_item = undef
if not $prev_item
or ( $prev_item->{itemnumber} == $items[0]->{itemnumber}
and ( @next_items or @prev_items <= 1 )
);
$result{starting_homebranch} = $start_homebranch if $start_homebranch;
$result{starting_location} = $start_location if $start_location;
$result{starting_ccode} = $start_ccode if $start_ccode;
return \%result;
# populate the items
@items = GetShelfInfo( @items );
return {
items => \@items,
next_item => $next_item,
prev_item => $prev_item,
starting_homebranch => $start_homebranch,
starting_location => $start_location,
starting_ccode => $start_ccode,
};
}
# This runs through a statement handle and pulls out all the items in it, fills
# them up with additional info that shelves want, and returns those as a list.
# populate an item list with its title and upc, oclc and isbn normalized.
# Not really intended to be exported.
sub GetShelfInfo {
my ($sth, $marcflavour) = @_;
my @items;
while (my $this_item = $sth->fetchrow_hashref()) {
my $this_biblio = GetBibData($this_item->{biblionumber});
next if (!defined($this_biblio));
$this_item->{'title'} = $this_biblio->{'title'};
my @items = @_;
my $marcflavour = C4::Context->preference("marcflavour");
my @valid_items;
for my $item ( @items ) {
my $this_biblio = GetBibData($item->{biblionumber});
next unless defined $this_biblio;
$item->{'title'} = $this_biblio->{'title'};
my $this_record = GetMarcBiblio($this_biblio->{'biblionumber'});
$this_item->{'browser_normalized_upc'} = GetNormalizedUPC($this_record,$marcflavour);
$this_item->{'browser_normalized_oclc'} = GetNormalizedOCLCNumber($this_record,$marcflavour);
$this_item->{'browser_normalized_isbn'} = GetNormalizedISBN(undef,$this_record,$marcflavour);
push @items, $this_item;
$item->{'browser_normalized_upc'} = GetNormalizedUPC($this_record,$marcflavour);
$item->{'browser_normalized_oclc'} = GetNormalizedOCLCNumber($this_record,$marcflavour);
$item->{'browser_normalized_isbn'} = GetNormalizedISBN(undef,$this_record,$marcflavour);
push @valid_items, $item;
}
return @items;
return @valid_items;
}
# Fetches some basic biblio data needed by the shelf stuff

125
koha-tmpl/opac-tmpl/prog/en/includes/shelfbrowser.inc

@ -0,0 +1,125 @@
[% BLOCK shelfbrowser %]
[% IF OpenOPACShelfBrowser %]
<div id="shelfbrowser">
<h5 style="text-align: center;">
[% IF ( starting_homebranch ) %]Browsing [% starting_homebranch %] Shelves[% END %]
[% IF ( starting_location ) %], Shelving location: [% starting_location %][% END %]
[% IF ( starting_ccode ) %], Collection code: [% starting_ccode %][% END %]
<a style="font-size: 75%;" href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% biblionumber %]" class="close_shelf" >Close shelf browser</a>
</h5>
<table>
<tr>
<td rowspan="2" style="width:20px;">
[% IF shelfbrowser_prev_item %]
<div id="browser_previous">
<a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% shelfbrowser_prev_item.biblionumber %]&amp;shelfbrowse_itemnumber=[% shelfbrowser_prev_item.itemnumber %]#shelfbrowser">Previous</a>
</div>
[% END %]
</td>
[% FOREACH item IN shelfbrowser_items %]
<td>
<a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% item.biblionumber %]&amp;shelfbrowse_itemnumber=[% item.itemnumber %]#shelfbrowser">
[% IF ( OPACLocalCoverImages ) %]
<div title="[% item.biblionumber |url %]" class="[% item.biblionumber %] thumbnail-shelfbrowser" id="local-thumbnail-shelf-[% item.biblionumber %]"></div>
[% END %]
[% IF ( OPACAmazonCoverImages ) %]
[% IF ( item.browser_normalized_isbn ) %]
<img border="0" src="http://images.amazon.com/images/P/[% item.browser_normalized_isbn %].01._AA75_PU_PU-5_.jpg" alt="" />
[% ELSE %]
<span class="no-image">No cover image available</span>
[% END %]
[% END %]
[% IF ( SyndeticsEnabled ) %]
[% IF ( SyndeticsCoverImages ) %]
[% IF ( content_identifier_exists ) %]
[% IF ( using_https ) %]
<img border="0" src="https://secure.syndetics.com/index.aspx?isbn=[% item.browser_normalized_isbn %]/SC.GIF&amp;client=[% SyndeticsClientCode %][% IF ( item.browser_normalized_upc ) %]&amp;upc=[% item.browser_normalized_upc %][% END %][% IF ( item.browser_normalized_oclc ) %]&amp;oclc=[% item.browser_normalized_oclc %][% END %]&amp;type=xw10" alt="" />
[% ELSE %]
<img border="0" src="http://www.syndetics.com/index.aspx?isbn=[% item.browser_normalized_isbn %]/SC.GIF&amp;client=[% SyndeticsClientCode %][% IF ( item.browser_normalized_upc ) %]&amp;upc=[% item.browser_normalized_upc %][% END %][% IF ( item.browser_normalized_oclc ) %]&amp;oclc=[% item.browser_normalized_oclc %][% END %]&amp;type=xw10" alt="" />
[% END %]
[% ELSE %]
<span class="no-image">No cover image available</span>
[% END %]
[% END %]
[% END %]
[% IF ( GoogleJackets ) %]
[% IF ( item.browser_normalized_isbn ) %]
<div style="block" title="[% item.biblionumber |url %]" class="[% item.browser_normalized_isbn %]" id="gbs-thumbnail-preview[% loop.count %]"></div>
[% ELSE %]
<span class="no-image">No cover image available</span>
[% END %]
[% END %]
[% IF ( BakerTaylorEnabled ) %]
[% IF ( item.browser_normalized_isbn ) %]
<img alt="See Baker &amp; Taylor" src="[% BakerTaylorImageURL |html %][% item.browser_normalized_isbn %]" />
[% ELSE %]
<span class="no-image">No cover image available</span>
[% END %]
[% END %]
</a>
</td>
[% END %]
<td rowspan="2" style="width:20px;">
[% IF shelfbrowser_next_item %]
<div id="browser_next">
<a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% shelfbrowser_prev_item.biblionumber %]&amp;shelfbrowse_itemnumber=[% shelfbrowser_prev_item.itemnumber %]#shelfbrowser">Next</a>
</div>
[% END %]
</td>
</tr>
<tr>
[% FOREACH item IN shelfbrowser_items %]
<td class="top">
[% item.itemcallnumber %]
<a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% item.biblionumber %]&amp;shelfbrowse_itemnumber=[% item.itemnumber %]#shelfbrowser">[% item.title |html %]</a>
</td>
[% END %]
</tr>
</table>
</div>
<script type="text/javascript">
$(document).ready(function(){
$(".close_shelf").click(function(e){
e.preventDefault();
$("#shelfbrowser").hide();
});
[% IF shelfbrowser_prev_item.itemnumber %]
$("#browser_previous a").click(function(e){
e.preventDefault();
$.ajax({
url: "/cgi-bin/koha/svc/shelfbrowser.pl",
type: "POST",
data: {
"shelfbrowse_itemnumber": [% shelfbrowser_prev_item.itemnumber %]
},
success: function(data){
$("#shelfbrowser").replaceWith(data);
}
});
});
[% END %]
[% IF shelfbrowser_next_item.itemnumber %]
$("#browser_next a").click(function(e){
e.preventDefault();
$.ajax({
url: "/cgi-bin/koha/svc/shelfbrowser.pl",
type: "POST",
data: {
"shelfbrowse_itemnumber": [% shelfbrowser_next_item.itemnumber %]
},
success: function(data){
$("#shelfbrowser").replaceWith(data);
}
});
});
[% END %]
});
</script>
[% END %]
[% END %][%# end of shelfbrowser block %]

135
koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt

@ -1068,6 +1068,7 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
[% END %]
[% END %]
[% PROCESS 'shelfbrowser.inc' %]
[% INCLUDE shelfbrowser tab='holdings' %]
<br clear="all" />
</div>
@ -1588,137 +1589,3 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
[% END %]</tbody>
</table>
[% END %][%# end of items_table block %]
[% BLOCK shelfbrowser %]
[% IF ( OpenOPACShelfBrowser and shelfbrowser_tab == tab) %]
<div id="shelfbrowser">
<h5 style="text-align: center;">
[% IF ( starting_homebranch ) %]Browsing [% starting_homebranch %] Shelves[% END %]
[% IF ( starting_location ) %], Shelving location: [% starting_location %][% END %]
[% IF ( starting_ccode ) %], Collection code: [% starting_ccode %][% END %]
<a style="font-size: 75%;" href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% biblionumber %]">Close shelf browser</a>
</h5>
<table>
<tr>
<td rowspan="2" style="width:20px;">
<div id="browser_previous">
<a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% IF ( shelfbrowser_prev_biblionumber ) %][% shelfbrowser_prev_biblionumber %][% ELSE %][% biblionumber %][% END %]&amp;shelfbrowse_itemnumber=[% shelfbrowser_prev_itemnumber %]#shelfbrowser">Previous</a>
</div>
</td>
[% FOREACH PREVIOUS_SHELF_BROWS IN PREVIOUS_SHELF_BROWSE %]
<td>
<a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% PREVIOUS_SHELF_BROWS.biblionumber %]&amp;shelfbrowse_itemnumber=[% PREVIOUS_SHELF_BROWS.itemnumber %]#shelfbrowser">
[% IF ( OPACLocalCoverImages ) %]
<div title="[% PREVIOUS_SHELF_BROWS.biblionumber |url %]" class="[% PREVIOUS_SHELF_BROWS.biblionumber %] thumbnail-shelfbrowser" id="local-thumbnail-shelf-[% PREVIOUS_SHELF_BROWS.biblionumber %]"></div>
[% END %]
[% IF ( OPACAmazonCoverImages ) %]
[% IF ( PREVIOUS_SHELF_BROWS.browser_normalized_isbn ) %]
<img border="0" src="http://images.amazon.com/images/P/[% PREVIOUS_SHELF_BROWS.browser_normalized_isbn %].01._AA75_PU_PU-5_.jpg" alt="" />
[% ELSE %]
<span class="no-image">No cover image available</span>
[% END %]
[% END %]
[% IF ( SyndeticsEnabled ) %]
[% IF ( SyndeticsCoverImages ) %]
[% IF ( content_identifier_exists ) %]
[% IF ( using_https ) %]
<img border="0" src="https://secure.syndetics.com/index.aspx?isbn=[% PREVIOUS_SHELF_BROWS.browser_normalized_isbn %]/SC.GIF&amp;client=[% SyndeticsClientCode %][% IF ( PREVIOUS_SHELF_BROWS.browser_normalized_upc ) %]&amp;upc=[% PREVIOUS_SHELF_BROWS.browser_normalized_upc %][% END %][% IF ( PREVIOUS_SHELF_BROWS.browser_normalized_oclc ) %]&amp;oclc=[% PREVIOUS_SHELF_BROWS.browser_normalized_oclc %][% END %]&amp;type=xw10" alt="" />
[% ELSE %]
<img border="0" src="http://www.syndetics.com/index.aspx?isbn=[% PREVIOUS_SHELF_BROWS.browser_normalized_isbn %]/SC.GIF&amp;client=[% SyndeticsClientCode %][% IF ( PREVIOUS_SHELF_BROWS.browser_normalized_upc ) %]&amp;upc=[% PREVIOUS_SHELF_BROWS.browser_normalized_upc %][% END %][% IF ( PREVIOUS_SHELF_BROWS.browser_normalized_oclc ) %]&amp;oclc=[% PREVIOUS_SHELF_BROWS.browser_normalized_oclc %][% END %]&amp;type=xw10" alt="" />
[% END %]
[% ELSE %]
<span class="no-image">No cover image available</span>
[% END %]
[% END %]
[% END %]
[% IF ( GoogleJackets ) %]
[% IF ( PREVIOUS_SHELF_BROWS.browser_normalized_isbn ) %]
<div style="block" title="[% PREVIOUS_SHELF_BROWS.biblionumber |url %]" class="[% PREVIOUS_SHELF_BROWS.browser_normalized_isbn %]" id="gbs-thumbnail-preview[% loop.count %]"></div>
[% ELSE %]
<span class="no-image">No cover image available</span>
[% END %]
[% END %]
[% IF ( BakerTaylorEnabled ) %]
[% IF ( PREVIOUS_SHELF_BROWS.browser_normalized_isbn ) %]
<img alt="See Baker &amp; Taylor" src="[% BakerTaylorImageURL |html %][% PREVIOUS_SHELF_BROWS.browser_normalized_isbn %]" />
[% ELSE %]
<span class="no-image">No cover image available</span>
[% END %]
[% END %]
</a>
</td>
[% END %]
[% FOREACH NEXT_SHELF_BROWS IN NEXT_SHELF_BROWSE %]
<td>
<a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% NEXT_SHELF_BROWS.biblionumber %]&amp;shelfbrowse_itemnumber=[% NEXT_SHELF_BROWS.itemnumber %]#shelfbrowser">
[% IF ( OPACLocalCoverImages ) %]
<div title="[% NEXT_SHELF_BROWS.biblionumber |url %]" class="[% NEXT_SHELF_BROWS.biblionumber %] thumbnail-shelfbrowser" id="local-thumbnail-shelf-[% NEXT_SHELF_BROWS.biblionumber %]"></div>
[% END %]
[% IF ( OPACAmazonCoverImages ) %]
[% IF ( NEXT_SHELF_BROWS.browser_normalized_isbn ) %]
<img border="0" src="http://images.amazon.com/images/P/[% NEXT_SHELF_BROWS.browser_normalized_isbn %].01._AA75_PU_PU-5_.jpg" alt="" />
[% ELSE %]
<span class="no-image">No cover image available</span>
[% END %]
[% END %]
[% IF ( SyndeticsEnabled ) %]
[% IF ( SyndeticsCoverImages ) %]
[% IF ( content_identifier_exists ) %]
[% IF ( using_https ) %]
<img border="0" src="https://secure.syndetics.com/index.aspx?isbn=[% NEXT_SHELF_BROWS.browser_normalized_isbn %]/SC.GIF&amp;client=[% SyndeticsClientCode %][% IF ( NEXT_SHELF_BROWS.browser_normalized_upc ) %]&amp;upc=[% NEXT_SHELF_BROWS.browser_normalized_upc %][% END %][% IF ( NEXT_SHELF_BROWS.browser_normalized_oclc ) %]&amp;oclc=[% NEXT_SHELF_BROWS.browser_normalized_oclc %][% END %]&amp;type=xw10" alt="" />
[% ELSE %]
<img border="0" src="http://www.syndetics.com/index.aspx?isbn=[% NEXT_SHELF_BROWS.browser_normalized_isbn %]/SC.GIF&amp;client=[% SyndeticsClientCode %][% IF ( NEXT_SHELF_BROWS.browser_normalized_upc ) %]&amp;upc=[% NEXT_SHELF_BROWS.browser_normalized_upc %][% END %][% IF ( NEXT_SHELF_BROWS.browser_normalized_oclc ) %]&amp;oclc=[% NEXT_SHELF_BROWS.browser_normalized_oclc %][% END %]&amp;type=xw10" alt="" />
[% END %]
[% ELSE %]
<span class="no-image">No cover image available</span>
[% END %]
[% END %]
[% END %]
[% IF ( GoogleJackets ) %]
[% IF ( NEXT_SHELF_BROWS.browser_normalized_isbn ) %]
<div style="block" title="[% NEXT_SHELF_BROWS.biblionumber |url %]" class="[% NEXT_SHELF_BROWS.browser_normalized_isbn %]" id="gbs-thumbnail-preview[% loop.count %]"></div>
[% ELSE %]
<span class="no-image">No cover image available</span>
[% END %]
[% END %]
[% IF ( BakerTaylorEnabled ) %]
[% IF ( NEXT_SHELF_BROWS.browser_normalized_isbn ) %]
<img alt="See Baker &amp; Taylor" src="[% BakerTaylorImageURL |html %][% NEXT_SHELF_BROWS.browser_normalized_isbn %]" />
[% ELSE %]
<span class="no-image">No cover image available</span>
[% END %]
[% END %]
</a>
</td>
[% END %]
<td rowspan="2">
<div id="browser_next">
<a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% IF ( shelfbrowser_next_biblionumber ) %][% shelfbrowser_next_biblionumber %][% ELSE %][% biblionumber %][% END %]&amp;shelfbrowse_itemnumber=[% shelfbrowser_next_itemnumber %]#shelfbrowser">Next</a>
</div>
</td>
</tr>
<tr>
[% FOREACH PREVIOUS_SHELF_BROWS IN PREVIOUS_SHELF_BROWSE %]
<td class="top">
[% PREVIOUS_SHELF_BROWS.itemcallnumber %]
<a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% PREVIOUS_SHELF_BROWS.biblionumber %]&amp;shelfbrowse_itemnumber=[% PREVIOUS_SHELF_BROWS.itemnumber %]#shelfbrowser">[% PREVIOUS_SHELF_BROWS.title |html %]</a>
</td>
[% END %]
[% FOREACH NEXT_SHELF_BROWS IN NEXT_SHELF_BROWSE %]
<td class="top" style="width:20px;">
[% NEXT_SHELF_BROWS.itemcallnumber %]
<a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% NEXT_SHELF_BROWS.biblionumber %]&amp;shelfbrowse_itemnumber=[% NEXT_SHELF_BROWS.itemnumber %]#shelfbrowser">[% NEXT_SHELF_BROWS.title |html %]</a>
</td>
[% END %]
</tr>
</table>
</div>
[% END %]
[% END %][%# end of shelfbrowser block %]

2
koha-tmpl/opac-tmpl/prog/en/modules/svc/shelfbrowser.tt

@ -0,0 +1,2 @@
[% PROCESS 'shelfbrowser.inc' %]
[% INCLUDE shelfbrowser %]

12
opac/opac-detail.pl

@ -928,19 +928,15 @@ if (C4::Context->preference("OPACShelfBrowser")) {
my $starting_itemnumber = $query->param('shelfbrowse_itemnumber');
if (defined($starting_itemnumber)) {
$template->param( OpenOPACShelfBrowser => 1) if $starting_itemnumber;
my $nearby = GetNearbyItems($starting_itemnumber,3);
my $nearby = GetNearbyItems($starting_itemnumber);
$template->param(
starting_homebranch => $nearby->{starting_homebranch}->{description},
starting_location => $nearby->{starting_location}->{description},
starting_ccode => $nearby->{starting_ccode}->{description},
starting_itemnumber => $nearby->{starting_itemnumber},
shelfbrowser_prev_itemnumber => $nearby->{prev_itemnumber},
shelfbrowser_next_itemnumber => $nearby->{next_itemnumber},
shelfbrowser_prev_biblionumber => $nearby->{prev_biblionumber},
shelfbrowser_next_biblionumber => $nearby->{next_biblionumber},
PREVIOUS_SHELF_BROWSE => $nearby->{prev},
NEXT_SHELF_BROWSE => $nearby->{next},
shelfbrowser_prev_item => $nearby->{prev_item},
shelfbrowser_next_item => $nearby->{next_item},
shelfbrowser_items => $nearby->{items},
);
# in which tab shelf browser should open ?

41
opac/svc/shelfbrowser.pl

@ -0,0 +1,41 @@
#!/usr/bin/perl
use Modern::Perl;
use CGI;
use C4::Auth;
use C4::Context;
use C4::Output;
use C4::ShelfBrowser;
my $cgi = new CGI;
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
{
template_name => "svc/shelfbrowser.tt",
query => $cgi,
type => "opac",
authnotrequired => ( C4::Context->preference("OpacPublic") ? 1 : 0 ),
flagsrequired => { borrow => 1 },
}
);
# Shelf Browser Stuff
if (C4::Context->preference("OPACShelfBrowser")) {
my $starting_itemnumber = $cgi->param('shelfbrowse_itemnumber');
if (defined($starting_itemnumber)) {
my $nearby = GetNearbyItems($starting_itemnumber);
$template->param(
starting_homebranch => $nearby->{starting_homebranch}->{description},
starting_location => $nearby->{starting_location}->{description},
starting_ccode => $nearby->{starting_ccode}->{description},
shelfbrowser_prev_item => $nearby->{prev_item},
shelfbrowser_next_item => $nearby->{next_item},
shelfbrowser_items => $nearby->{items},
OpenOPACShelfBrowser => 1,
);
}
}
print $template->output;

212
t/db_dependent/ShelfBrowser.t

@ -0,0 +1,212 @@
#!/usr/bin/perl
use Modern::Perl;
use Test::More tests => 74;
use List::Util qw( shuffle );
use MARC::Field;
use MARC::Record;
use C4::Biblio;
use C4::Context;
use C4::Items;
use_ok('C4::ShelfBrowser');
my $dbh = C4::Context->dbh;
$dbh->{AutoCommit} = 0;
$dbh->{RaiseError} = 1;
$dbh->do(q|DELETE FROM reserves|);
$dbh->do(q|DELETE FROM issues|);
$dbh->do(q|DELETE FROM items|);
my $cn;
# 100.100 150.100 200.100 210.100 300.000 320.000 400.100 410.100 500.100 510.100 520.100 600.000 610.000 700.100 710.100 720.100 730.100 740.100 750.100
my @callnumbers = qw(
100.100
150.100
200.100
210.100
300.000
320.000
400.100
410.100
500.100
510.100
520.100
600.000
610.000
700.100
710.100
720.100
730.100
740.100
750.100
);
my $record = MARC::Record->new();
$record->append_fields(
MARC::Field->new('100', ' ', ' ', a => 'Donald E. Knuth.'),
MARC::Field->new('245', ' ', ' ', a => 'The art of computer programming'),
);
my ( $biblionumber, undef, undef ) = C4::Biblio::AddBiblio($record, '');
for my $callnumber ( shuffle @callnumbers ) {
my ( $biblionumber, undef, $itemnumber ) = C4::Items::AddItem({
homebranch => 'CPL',
holdingbranch => 'CPL',
itemcallnumber => $callnumber,
}, $biblionumber);
$cn->{$callnumber} = {
biblionumber => $biblionumber,
itemnumber => $itemnumber,
itemcallnumber => $callnumber,
}
}
my $nearby;
$nearby = C4::ShelfBrowser::GetNearbyItems( $cn->{'500.100'}{itemnumber} );
# We have
# < 320.000 400.100 410.100 500.100 510.100 520.100 600.000 >
# 6 7 8 [9] 10 11 12
# Clicking on previous, we want a link to 150.100
is( $nearby->{prev_item}{itemcallnumber}, '150.100', "Simple case: previous link 1/2" );
is( $nearby->{prev_item}{itemnumber}, $cn->{'150.100'}{itemnumber}, "Simple case: previous link 2/2" );
# Clicking on next, we want a link to 730.100
is( $nearby->{next_item}{itemcallnumber}, '720.100', "Simple case: next link 1/2" );
is( $nearby->{next_item}{itemnumber}, $cn->{'720.100'}{itemnumber}, "Simple case: next link 2/2" );
is( $nearby->{items}[0]{itemcallnumber}, '320.000', "Simple case: item 1");
is( $nearby->{items}[1]{itemcallnumber}, '400.100', "Simple case: item 2");
is( $nearby->{items}[2]{itemcallnumber}, '410.100', "Simple case: item 3");
is( $nearby->{items}[3]{itemcallnumber}, '500.100', "Simple case: item 4");
is( $nearby->{items}[4]{itemcallnumber}, '510.100', "Simple case: item 5");
is( $nearby->{items}[5]{itemcallnumber}, '520.100', "Simple case: item 6");
is( $nearby->{items}[6]{itemcallnumber}, '600.000', "Simple case: item 7");
$nearby = C4::ShelfBrowser::GetNearbyItems( $cn->{'500.100'}{itemnumber}, 2, 3 );
# We have
# < 400.100 410.100 500.100 510.100 520.100 >
# 7 8 [9] 10 11
# Clicking on previous, we want a link to 320.000
is( $nearby->{prev_item}{itemcallnumber}, '320.000', "Test gap: previous link 1/2" );
is( $nearby->{prev_item}{itemnumber}, $cn->{'320.000'}{itemnumber}, "Test gap: previous link 2/2" );
# Clicking on next, we want a link to 600.000
is( $nearby->{next_item}{itemcallnumber}, '600.000', "Test gap: next link 1/2" );
is( $nearby->{next_item}{itemnumber}, $cn->{'600.000'}{itemnumber}, "Test gap: next link 2/2" );
is( scalar( @{$nearby->{items}} ), 5, "Test gap: got 5 items" );
is( $nearby->{items}[0]{itemcallnumber}, '400.100', "Test gap: item 1");
is( $nearby->{items}[1]{itemcallnumber}, '410.100', "Test gap: item 2");
is( $nearby->{items}[2]{itemcallnumber}, '500.100', "Test gap: item 3");
is( $nearby->{items}[3]{itemcallnumber}, '510.100', "Test gap: item 4");
is( $nearby->{items}[4]{itemcallnumber}, '520.100', "Test gap: item 5");
$nearby = C4::ShelfBrowser::GetNearbyItems( $cn->{'300.000'}{itemnumber} );
# We have
# < 150.100 200.100 210.100 300.000 320.000 400.100 410.100 >
# 2 3 4 [5] 6 7 8
# Clicking on previous, we want a link to 100.100
is( $nearby->{prev_item}{itemcallnumber}, '100.100', "Test start shelf: previous link 1/2" );
is( $nearby->{prev_item}{itemnumber}, $cn->{'100.100'}{itemnumber}, "Test start shelf: previous link 2/2" );
# Clicking on next, we want a link to 600.000
is( $nearby->{next_item}{itemcallnumber}, '600.000', "Test start shelf: next link 1/2" );
is( $nearby->{next_item}{itemnumber}, $cn->{'600.000'}{itemnumber}, "Test start shelf: next link 2/2" );
is( $nearby->{items}[0]{itemcallnumber}, '150.100', "Test start shelf: item 1");
is( $nearby->{items}[1]{itemcallnumber}, '200.100', "Test start shelf: item 2");
is( $nearby->{items}[2]{itemcallnumber}, '210.100', "Test start shelf: item 3");
is( $nearby->{items}[3]{itemcallnumber}, '300.000', "Test start shelf: item 4");
is( $nearby->{items}[4]{itemcallnumber}, '320.000', "Test start shelf: item 5");
is( $nearby->{items}[5]{itemcallnumber}, '400.100', "Test start shelf: item 6");
is( $nearby->{items}[6]{itemcallnumber}, '410.100', "Test start shelf: item 7");
$nearby = C4::ShelfBrowser::GetNearbyItems( $cn->{'100.100'}{itemnumber} );
# We have
# 100.100 150.100 200.100 210.100 >
# [1] 2 3 4
# There is no previous link
is( $nearby->{prev_item}, undef, "Test first item on a shelf: no previous link" );
# Clicking on next, we want a link to 410.100
is( $nearby->{next_item}{itemcallnumber}, '410.100', "Test first item on a shelf: next link 1/2" );
is( $nearby->{next_item}{itemnumber}, $cn->{'410.100'}{itemnumber}, "Test first item on a shelf: next link 2/2" );
is( scalar( @{$nearby->{items}} ), 4, "Test first item on a shelf: There are 4 items displayed" );
is( $nearby->{items}[0]{itemcallnumber}, '100.100', "Test first item on a shelf: item 1");
is( $nearby->{items}[1]{itemcallnumber}, '150.100', "Test first item on a shelf: item 2");
is( $nearby->{items}[2]{itemcallnumber}, '200.100', "Test first item on a shelf: item 3");
is( $nearby->{items}[3]{itemcallnumber}, '210.100', "Test first item on a shelf: item 4");
$nearby = C4::ShelfBrowser::GetNearbyItems( $cn->{'150.100'}{itemnumber} );
# We have
# 100.100 150.100 200.100 210.100 300.000 >
# 1 [2] 3 4 5
# There is no previous link
is( $nearby->{prev_item}, undef, "Test second item on a shelf: no previous link" );
# Clicking on next, we want a link to 500.100
is( $nearby->{next_item}{itemcallnumber}, '500.100', "Test second item on a shelf: next link 1/2" );
is( $nearby->{next_item}{itemnumber}, $cn->{'500.100'}{itemnumber}, "Test second item on a shelf: next link 2/2" );
is( scalar( @{$nearby->{items}} ), 5, "Test second item on a shelf: got 5 items" );
is( $nearby->{items}[0]{itemcallnumber}, '100.100', "Test second item on a shelf: item 1");
is( $nearby->{items}[1]{itemcallnumber}, '150.100', "Test second item on a shelf: item 2");
is( $nearby->{items}[2]{itemcallnumber}, '200.100', "Test second item on a shelf: item 3");
is( $nearby->{items}[3]{itemcallnumber}, '210.100', "Test second item on a shelf: item 4");
is( $nearby->{items}[4]{itemcallnumber}, '300.000', "Test second item on a shelf: item 5");
$nearby = C4::ShelfBrowser::GetNearbyItems( $cn->{'710.100'}{itemnumber} );
# We have
# < 600.000 610.000 700.100 710.100 720.100 730.100 740.100 >
# 12 13 14 [15] 16 17 18
# Clicking on previous, we want a link to 410.100
is( $nearby->{prev_item}{itemcallnumber}, '410.100', "Test end shelf: previous link 1/2" );
is( $nearby->{prev_item}{itemnumber}, $cn->{'410.100'}{itemnumber}, "Test end shelf: previous link 2/2" );
# Clicking on next, we want a link to 730.100
is( $nearby->{next_item}{itemcallnumber}, '750.100', "Test end shelf: next link is a link to the last item 1/2" );
is( $nearby->{next_item}{itemnumber}, $cn->{'750.100'}{itemnumber}, "Test end shelf: next link is a link to the last item 2/2" );
is( $nearby->{items}[0]{itemcallnumber}, '600.000', "Test end shelf: item 1");
is( $nearby->{items}[1]{itemcallnumber}, '610.000', "Test end shelf: item 2");
is( $nearby->{items}[2]{itemcallnumber}, '700.100', "Test end shelf: item 3");
is( $nearby->{items}[3]{itemcallnumber}, '710.100', "Test end shelf: item 4");
is( $nearby->{items}[4]{itemcallnumber}, '720.100', "Test end shelf: item 5");
is( $nearby->{items}[5]{itemcallnumber}, '730.100', "Test end shelf: item 6");
is( $nearby->{items}[6]{itemcallnumber}, '740.100', "Test end shelf: item 7");
$nearby = C4::ShelfBrowser::GetNearbyItems( $cn->{'740.100'}{itemnumber} );
# We have
# < 710.100 720.100 730.100 740.100 750.100
# 15 16 17 [18] 19
# Clicking on previous, we want a link to
is( $nearby->{prev_item}{itemcallnumber}, '520.100', "Test end of the shelf: previous link 1/2" );
is( $nearby->{prev_item}{itemnumber}, $cn->{'520.100'}{itemnumber}, "Test end of the shelf: previous link 2/2" );
# No next link
is( $nearby->{next_item}, undef, "Test end of the shelf: no next link" );
is( scalar( @{$nearby->{items}} ), 5, "Test end of the shelf: got 5 items" );
is( $nearby->{items}[0]{itemcallnumber}, '710.100', "Test end of the shelf: item 1");
is( $nearby->{items}[1]{itemcallnumber}, '720.100', "Test end of the shelf: item 2");
is( $nearby->{items}[2]{itemcallnumber}, '730.100', "Test end of the shelf: item 3");
is( $nearby->{items}[3]{itemcallnumber}, '740.100', "Test end of the shelf: item 4");
is( $nearby->{items}[4]{itemcallnumber}, '750.100', "Test end of the shelf: item 5");
$nearby = C4::ShelfBrowser::GetNearbyItems( $cn->{'750.100'}{itemnumber} );
# We have
# < 720.100 730.100 740.100 750.100
# 16 17 18 [19]
# Clicking on previous, we want a link to
is( $nearby->{prev_item}{itemcallnumber}, '600.000', "Test last item of the shelf: previous link 1/2" );
is( $nearby->{prev_item}{itemnumber}, $cn->{'600.000'}{itemnumber}, "Test last item of the shelf: previous link 2/2" );
# No next link
is( $nearby->{next_item}, undef, "Test end of the shelf: no next link" );
is( scalar( @{$nearby->{items}} ), 4, "Test last item of the shelf: got 4 items" );
$dbh->rollback;
Loading…
Cancel
Save