Jonathan Druart
82cf4b82c2
hidden_items was not passed to XSLTParse4Display 2 things: * Should we hide the biblio record if OpacHiddenItemsHidesRecord is set? * allow_onshelf_holds is not working like in other scripts, what's the expected behaviour? If hidden should we completely ignore the item? Test plan: 1. Without the patch 2. fill OpacHiddenItems with «damaged: [1]» 3. find a record with several item 4. mark one of them as damaged 5. OPAC: go to the record, you shouldn't see the damaged item 6. add the record to a list 7. see the list 8. in Availability you see the damaged item mentioned, this is the issue 9. apply the patches and restart the services 10. the list should not mention the damaged item :D Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net> Signed-off-by: David Nind <david@davidnind.com> Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de> Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org> Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
453 lines
18 KiB
Perl
Executable file
453 lines
18 KiB
Perl
Executable file
#!/usr/bin/perl
|
|
|
|
# Copyright 2015 Koha Team
|
|
#
|
|
# 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 <http://www.gnu.org/licenses>.
|
|
|
|
use Modern::Perl;
|
|
|
|
use CGI qw ( -utf8 );
|
|
use C4::Auth;
|
|
use C4::Biblio;
|
|
use C4::External::BakerTaylor qw( image_url link_url );
|
|
use C4::Koha;
|
|
use C4::Items;
|
|
use C4::Members;
|
|
use C4::Output;
|
|
use C4::Tags qw( get_tags );
|
|
use C4::XSLT;
|
|
|
|
use Koha::Biblios;
|
|
use Koha::Biblioitems;
|
|
use Koha::CirculationRules;
|
|
use Koha::CsvProfiles;
|
|
use Koha::Items;
|
|
use Koha::ItemTypes;
|
|
use Koha::Patrons;
|
|
use Koha::Virtualshelves;
|
|
use Koha::RecordProcessor;
|
|
|
|
use constant ANYONE => 2;
|
|
|
|
my $query = CGI->new;
|
|
|
|
my $template_name = $query->param('rss') ? "opac-shelves-rss.tt" : "opac-shelves.tt";
|
|
|
|
# if virtualshelves is disabled, leave immediately
|
|
if ( ! C4::Context->preference('virtualshelves') ) {
|
|
print $query->redirect("/cgi-bin/koha/errors/404.pl");
|
|
exit;
|
|
}
|
|
|
|
my $op = $query->param('op') || 'list';
|
|
my ( $template, $loggedinuser, $cookie );
|
|
|
|
if( $op eq 'view' || $op eq 'list' ){
|
|
( $template, $loggedinuser, $cookie ) = get_template_and_user({
|
|
template_name => $template_name,
|
|
query => $query,
|
|
type => "opac",
|
|
authnotrequired => ( C4::Context->preference("OpacPublic") ? 1 : 0 ),
|
|
});
|
|
} else {
|
|
( $template, $loggedinuser, $cookie ) = get_template_and_user({
|
|
template_name => $template_name,
|
|
query => $query,
|
|
type => "opac",
|
|
authnotrequired => 0,
|
|
});
|
|
}
|
|
|
|
if (C4::Context->preference("BakerTaylorEnabled")) {
|
|
$template->param(
|
|
BakerTaylorImageURL => &image_url(),
|
|
BakerTaylorLinkURL => &link_url(),
|
|
);
|
|
}
|
|
|
|
my $referer = $query->param('referer') || $op;
|
|
my $category = 1;
|
|
$category = 2 if $query->param('category') && $query->param('category') == 2;
|
|
|
|
my ( $shelf, $shelfnumber, @messages );
|
|
|
|
if ( $op eq 'add_form' ) {
|
|
# Only pass default
|
|
$shelf = { allow_change_from_owner => 1 };
|
|
} elsif ( $op eq 'edit_form' ) {
|
|
$shelfnumber = $query->param('shelfnumber');
|
|
$shelf = Koha::Virtualshelves->find($shelfnumber);
|
|
|
|
if ( $shelf ) {
|
|
$category = $shelf->category;
|
|
my $patron = Koha::Patrons->find( $shelf->owner );
|
|
$template->param( owner => $patron, );
|
|
unless ( $shelf->can_be_managed( $loggedinuser ) ) {
|
|
push @messages, { type => 'error', code => 'unauthorized_on_update' };
|
|
$op = 'list';
|
|
}
|
|
} else {
|
|
push @messages, { type => 'error', code => 'does_not_exist' };
|
|
}
|
|
} elsif ( $op eq 'add' ) {
|
|
if ( $loggedinuser ) {
|
|
my $allow_changes_from = $query->param('allow_changes_from');
|
|
eval {
|
|
$shelf = Koha::Virtualshelf->new(
|
|
{ shelfname => scalar $query->param('shelfname'),
|
|
sortfield => scalar $query->param('sortfield'),
|
|
category => $category,
|
|
allow_change_from_owner => $allow_changes_from > 0,
|
|
allow_change_from_others => $allow_changes_from == ANYONE,
|
|
owner => scalar $loggedinuser,
|
|
}
|
|
);
|
|
$shelf->store;
|
|
$shelfnumber = $shelf->shelfnumber;
|
|
};
|
|
if ($@) {
|
|
push @messages, { type => 'error', code => ref($@), msg => $@ };
|
|
} elsif ( not $shelf ) {
|
|
push @messages, { type => 'error', code => 'error_on_insert' };
|
|
} else {
|
|
push @messages, { type => 'message', code => 'success_on_insert' };
|
|
$op = 'view';
|
|
}
|
|
} else {
|
|
push @messages, { type => 'error', code => 'unauthorized_on_insert' };
|
|
$op = 'list';
|
|
}
|
|
} elsif ( $op eq 'edit' ) {
|
|
$shelfnumber = $query->param('shelfnumber');
|
|
$shelf = Koha::Virtualshelves->find($shelfnumber);
|
|
if ( $shelf ) {
|
|
$op = $referer;
|
|
my $sortfield = $query->param('sortfield');
|
|
$sortfield = 'title' unless grep { $_ eq $sortfield } qw( title author copyrightdate itemcallnumber dateadded );
|
|
if ( $shelf->can_be_managed( $loggedinuser ) ) {
|
|
$shelf->shelfname( scalar $query->param('shelfname') );
|
|
$shelf->sortfield( $sortfield );
|
|
my $allow_changes_from = $query->param('allow_changes_from');
|
|
$shelf->allow_change_from_owner( $allow_changes_from > 0 );
|
|
$shelf->allow_change_from_others( $allow_changes_from == ANYONE );
|
|
$shelf->category( $category );
|
|
eval { $shelf->store };
|
|
|
|
if ($@) {
|
|
push @messages, { type => 'error', code => 'error_on_update' };
|
|
$op = 'edit_form';
|
|
} else {
|
|
push @messages, { type => 'message', code => 'success_on_update' };
|
|
}
|
|
} else {
|
|
push @messages, { type => 'error', code => 'unauthorized_on_update' };
|
|
}
|
|
} else {
|
|
push @messages, { type => 'error', code => 'does_not_exist' };
|
|
}
|
|
} elsif ( $op eq 'delete' ) {
|
|
$shelfnumber = $query->param('shelfnumber');
|
|
$shelf = Koha::Virtualshelves->find($shelfnumber);
|
|
if ($shelf) {
|
|
if ( $shelf->can_be_deleted( $loggedinuser ) ) {
|
|
eval { $shelf->delete; };
|
|
if ($@) {
|
|
push @messages, { type => 'error', code => ref($@), msg => $@ };
|
|
} else {
|
|
push @messages, { type => 'message', code => 'success_on_delete' };
|
|
}
|
|
} else {
|
|
push @messages, { type => 'error', code => 'unauthorized_on_delete' };
|
|
}
|
|
} else {
|
|
push @messages, { type => 'error', code => 'does_not_exist' };
|
|
}
|
|
$op = $referer;
|
|
} elsif ( $op eq 'remove_share' ) {
|
|
$shelfnumber = $query->param('shelfnumber');
|
|
$shelf = Koha::Virtualshelves->find($shelfnumber);
|
|
if ($shelf) {
|
|
my $removed = eval { $shelf->remove_share( $loggedinuser ); };
|
|
if ($@) {
|
|
push @messages, { type => 'error', code => ref($@), msg => $@ };
|
|
} elsif ( $removed ) {
|
|
push @messages, { type => 'message', code => 'success_on_remove_share' };
|
|
} else {
|
|
push @messages, { type => 'error', code => 'error_on_remove_share' };
|
|
}
|
|
} else {
|
|
push @messages, { type => 'error', code => 'does_not_exist' };
|
|
}
|
|
$op = $referer;
|
|
|
|
} elsif ( $op eq 'add_biblio' ) {
|
|
$shelfnumber = $query->param('shelfnumber');
|
|
$shelf = Koha::Virtualshelves->find($shelfnumber);
|
|
if ($shelf) {
|
|
if( my $barcode = $query->param('barcode') ) {
|
|
my $item = Koha::Items->find({ barcode => $barcode });
|
|
if ( $item ) {
|
|
if ( $shelf->can_biblios_be_added( $loggedinuser ) ) {
|
|
my $added = eval { $shelf->add_biblio( $item->biblionumber, $loggedinuser ); };
|
|
if ($@) {
|
|
push @messages, { type => 'error', code => ref($@), msg => $@ };
|
|
} elsif ( $added ) {
|
|
push @messages, { type => 'message', code => 'success_on_add_biblio' };
|
|
} else {
|
|
push @messages, { type => 'message', code => 'error_on_add_biblio' };
|
|
}
|
|
} else {
|
|
push @messages, { type => 'error', code => 'unauthorized_on_add_biblio' };
|
|
}
|
|
} else {
|
|
push @messages, { type => 'error', code => 'item_does_not_exist' };
|
|
}
|
|
}
|
|
} else {
|
|
push @messages, { type => 'error', code => 'does_not_exist' };
|
|
}
|
|
$op = $referer;
|
|
} elsif ( $op eq 'remove_biblios' ) {
|
|
$shelfnumber = $query->param('shelfnumber');
|
|
$shelf = Koha::Virtualshelves->find($shelfnumber);
|
|
my @biblionumber = $query->multi_param('biblionumber');
|
|
if ($shelf) {
|
|
if ( $shelf->can_biblios_be_removed( $loggedinuser ) ) {
|
|
my $number_of_biblios_removed = eval {
|
|
$shelf->remove_biblios(
|
|
{
|
|
biblionumbers => \@biblionumber,
|
|
borrowernumber => $loggedinuser,
|
|
}
|
|
);
|
|
};
|
|
if ($@) {
|
|
push @messages, { type => 'error', code => ref($@), msg => $@ };
|
|
} elsif ( $number_of_biblios_removed ) {
|
|
push @messages, { type => 'message', code => 'success_on_remove_biblios' };
|
|
} else {
|
|
push @messages, { type => 'error', code => 'no_biblio_removed' };
|
|
}
|
|
} else {
|
|
push @messages, { type => 'error', code => 'unauthorized_on_remove_biblios' };
|
|
}
|
|
} else {
|
|
push @messages, { type => 'error', code => 'does_not_exist' };
|
|
}
|
|
$op = 'view';
|
|
}
|
|
|
|
if ( $op eq 'view' ) {
|
|
$shelfnumber ||= $query->param('shelfnumber');
|
|
$shelf = Koha::Virtualshelves->find($shelfnumber);
|
|
if ( $shelf ) {
|
|
if ( $shelf->can_be_viewed( $loggedinuser ) ) {
|
|
$category = $shelf->category;
|
|
my( $sortfield, $direction );
|
|
if( defined( $query->param('sortfield') ) ){ # Passed in sorting overrides default sorting
|
|
( $sortfield, $direction ) = split /:/, $query->param('sortfield');
|
|
} else {
|
|
$sortfield = $shelf->sortfield;
|
|
$direction = 'asc';
|
|
}
|
|
$sortfield = 'title' unless grep $_ eq $sortfield, qw( title author copyrightdate itemcallnumber dateadded );
|
|
$direction = 'asc' if $direction ne 'asc' and $direction ne 'desc';
|
|
my ( $page, $rows );
|
|
unless ( $query->param('print') or $query->param('rss') ) {
|
|
$rows = C4::Context->preference('OPACnumSearchResults') || 20;
|
|
$page = ( $query->param('page') ? $query->param('page') : 1 );
|
|
}
|
|
my $order_by = $sortfield eq 'itemcallnumber' ? 'items.cn_sort' : $sortfield;
|
|
my $contents = $shelf->get_contents->search(
|
|
{},
|
|
{
|
|
prefetch => [ { 'biblionumber' => { 'biblioitems' => 'items' } } ],
|
|
page => $page,
|
|
rows => $rows,
|
|
order_by => { "-$direction" => $order_by },
|
|
}
|
|
);
|
|
|
|
# get biblionumbers stored in the cart
|
|
my @cart_list;
|
|
if(my $cart_list = $query->cookie('bib_list')){
|
|
@cart_list = split(/\//, $cart_list);
|
|
}
|
|
|
|
my $patron = Koha::Patrons->find( $loggedinuser );
|
|
|
|
my $categorycode; # needed for may_article_request
|
|
if( C4::Context->preference('ArticleRequests') ) {
|
|
$categorycode = $patron ? $patron->categorycode : undef;
|
|
}
|
|
|
|
# Lists display falls back to search results configuration
|
|
my $xslfile = C4::Context->preference('OPACXSLTListsDisplay');
|
|
my $lang = $xslfile ? C4::Languages::getlanguage() : undef;
|
|
my $sysxml = $xslfile ? C4::XSLT::get_xslt_sysprefs() : undef;
|
|
|
|
my $record_processor = Koha::RecordProcessor->new({ filters => 'ViewPolicy' });
|
|
|
|
my $art_req_itypes;
|
|
if( C4::Context->preference('ArticleRequests') ) {
|
|
$art_req_itypes = Koha::CirculationRules->guess_article_requestable_itemtypes({ $patron ? ( categorycode => $patron->categorycode ) : () });
|
|
}
|
|
|
|
my @items_info;
|
|
while ( my $content = $contents->next ) {
|
|
my $biblionumber = $content->biblionumber;
|
|
my $this_item = GetBiblioData($biblionumber);
|
|
my $record = GetMarcBiblio({ biblionumber => $biblionumber });
|
|
my $framework = GetFrameworkCode( $biblionumber );
|
|
my $biblio = Koha::Biblios->find( $biblionumber );
|
|
$record_processor->options({
|
|
interface => 'opac',
|
|
frameworkcode => $framework
|
|
});
|
|
$record_processor->process($record);
|
|
|
|
my $marcflavour = C4::Context->preference("marcflavour");
|
|
my $itemtype = Koha::Biblioitems->search({ biblionumber => $content->biblionumber })->next->itemtype;
|
|
$itemtype = Koha::ItemTypes->find( $itemtype );
|
|
if( $itemtype ) {
|
|
$this_item->{imageurl} = C4::Koha::getitemtypeimagelocation( 'opac', $itemtype->imageurl );
|
|
$this_item->{description} = $itemtype->description; #FIXME Should not it be translated_description?
|
|
$this_item->{notforloan} = $itemtype->notforloan;
|
|
}
|
|
$this_item->{'coins'} = $biblio->get_coins;
|
|
$this_item->{'normalized_upc'} = GetNormalizedUPC( $record, $marcflavour );
|
|
$this_item->{'normalized_ean'} = GetNormalizedEAN( $record, $marcflavour );
|
|
$this_item->{'normalized_oclc'} = GetNormalizedOCLCNumber( $record, $marcflavour );
|
|
$this_item->{'normalized_isbn'} = GetNormalizedISBN( undef, $record, $marcflavour );
|
|
# BZ17530: 'Intelligent' guess if result can be article requested
|
|
$this_item->{artreqpossible} = ( $art_req_itypes->{ $this_item->{itemtype} // q{} } || $art_req_itypes->{ '*' } ) ? 1 : q{};
|
|
|
|
unless ( defined $this_item->{size} ) {
|
|
|
|
#TT has problems with size
|
|
$this_item->{size} = q||;
|
|
}
|
|
|
|
if (C4::Context->preference('TagsEnabled') and C4::Context->preference('TagsShowOnList')) {
|
|
$this_item->{TagLoop} = get_tags({
|
|
biblionumber => $biblionumber, approved=>1, 'sort'=>'-weight',
|
|
limit => C4::Context->preference('TagsShowOnList'),
|
|
});
|
|
}
|
|
|
|
my @items;
|
|
my $items = $biblio->items;
|
|
my $allow_onshelf_holds;
|
|
my @hidden_items;
|
|
while ( my $item = $items->next ) {
|
|
if ( $item->hidden_in_opac({rules => C4::Context->yaml_preference('OpacHiddenItems')} ) ) {
|
|
push @hidden_items, $item->itemnumber;
|
|
next;
|
|
}
|
|
|
|
$allow_onshelf_holds ||= Koha::CirculationRules->get_onshelfholds_policy(
|
|
{ item => $item, patron => $patron } );
|
|
|
|
push @items, $item; # This is for non-xslt only
|
|
}
|
|
$this_item->{allow_onshelf_holds} = $allow_onshelf_holds;
|
|
$this_item->{'ITEM_RESULTS'} = \@items;
|
|
|
|
if ($xslfile) {
|
|
my $variables = {
|
|
anonymous_session => ($loggedinuser) ? 0 : 1
|
|
};
|
|
$this_item->{XSLTBloc} = XSLTParse4Display(
|
|
$biblionumber, $record,
|
|
"OPACXSLTListsDisplay", 1,
|
|
\@hidden_items, $sysxml,
|
|
$xslfile, $lang,
|
|
$variables
|
|
);
|
|
}
|
|
|
|
if ( grep {$_ eq $biblionumber} @cart_list) {
|
|
$this_item->{incart} = 1;
|
|
}
|
|
|
|
$this_item->{biblio_object} = $biblio;
|
|
$this_item->{biblionumber} = $biblionumber;
|
|
push @items_info, $this_item;
|
|
}
|
|
|
|
$template->param(
|
|
can_manage_shelf => $shelf->can_be_managed($loggedinuser),
|
|
can_delete_shelf => $shelf->can_be_deleted($loggedinuser),
|
|
can_remove_biblios => $shelf->can_biblios_be_removed($loggedinuser),
|
|
can_add_biblios => $shelf->can_biblios_be_added($loggedinuser),
|
|
itemsloop => \@items_info,
|
|
sortfield => $sortfield,
|
|
direction => $direction,
|
|
csv_profiles => [
|
|
Koha::CsvProfiles->search(
|
|
{ type => 'marc', used_for => 'export_records', staff_only => 0 }
|
|
)
|
|
],
|
|
);
|
|
if ( $page ) {
|
|
my $pager = $contents->pager;
|
|
$template->param(
|
|
pagination_bar => pagination_bar(
|
|
q||, $pager->last_page - $pager->first_page + 1,
|
|
$page, "page", { op => 'view', shelfnumber => $shelf->shelfnumber, sortfield => $sortfield, direction => $direction, }
|
|
),
|
|
);
|
|
}
|
|
} else {
|
|
push @messages, { type => 'error', code => 'unauthorized_on_view' };
|
|
undef $shelf;
|
|
}
|
|
} else {
|
|
push @messages, { type => 'error', code => 'does_not_exist' };
|
|
}
|
|
}
|
|
|
|
if ( $op eq 'list' ) {
|
|
my $shelves;
|
|
my ( $page, $rows ) = ( $query->param('page') || 1, 20 );
|
|
if ( $category == 1 ) {
|
|
$shelves = Koha::Virtualshelves->get_private_shelves({ page => $page, rows => $rows, borrowernumber => $loggedinuser, });
|
|
} else {
|
|
$shelves = Koha::Virtualshelves->get_public_shelves({ page => $page, rows => $rows, });
|
|
}
|
|
|
|
my $pager = $shelves->pager;
|
|
$template->param(
|
|
shelves => $shelves,
|
|
pagination_bar => pagination_bar(
|
|
q||, $pager->last_page - $pager->first_page + 1,
|
|
$page, "page", { op => 'list', category => $category, }
|
|
),
|
|
);
|
|
}
|
|
|
|
$template->param(
|
|
op => $op,
|
|
referer => $referer,
|
|
shelf => $shelf,
|
|
messages => \@messages,
|
|
category => $category,
|
|
print => scalar $query->param('print') || 0,
|
|
listsview => 1,
|
|
);
|
|
|
|
my $content_type = $query->param('rss')? 'rss' : 'html';
|
|
output_with_http_headers $query, $cookie, $template->output, $content_type;
|