use C4::Reserves; # CheckReserves
use C4::Debug;
use C4::Items;
+use C4::Charset;
use YAML;
use URI::Escape;
+use Business::ISBN;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $DEBUG);
&NZgetRecords
&AddSearchHistory
&GetDistinctValues
- &BiblioAddAuthorities
+ &enabled_staff_search_views
);
-#FIXME: i had to add BiblioAddAuthorities here because in Biblios.pm it caused circular dependencies (C4::Search uses C4::Biblio, and BiblioAddAuthorities uses SimpleSearch from C4::Search)
# make all your functions, whether exported or not;
'Authority-Number',
'authtype',
'bc',
+ 'Bib-level',
'biblionumber',
'bio',
'biography',
my $stopwords_removed; # flag to determine if stopwords have been removed
- my $cclq;
+ my $cclq = 0;
my $cclindexes = getIndexes();
- if( $query !~ /\s*ccl=/ ){
- for my $index (@$cclindexes){
- if($query =~ /($index)(,?\w)*[:=]/){
- $cclq = 1;
- }
+ if ( $query !~ /\s*ccl=/ ) {
+ while ( !$cclq && $query =~ /(?:^|\W)([\w-]+)(,[\w-]+)*[:=]/g ) {
+ my $dx = lc($1);
+ $cclq = grep { lc($_) eq $dx } @$cclindexes;
}
- $query = "ccl=$query" if($cclq);
+ $query = "ccl=$query" if $cclq;
}
# for handling ccl, cql, pqf queries in diagnostic mode, skip the rest of the steps
# IMO this subroutine is pretty messy still -- it's responsible for
# building the HTML output for the template
sub searchResults {
- my ( $search_context, $searchdesc, $hits, $results_per_page, $offset, $scan, @marcresults, $hidelostitems ) = @_;
+ my ( $search_context, $searchdesc, $hits, $results_per_page, $offset, $scan, $marcresults ) = @_;
my $dbh = C4::Context->dbh;
my @newresults;
- $search_context = 'opac' unless $search_context eq 'opac' or $search_context eq 'intranet';
+ $search_context = 'opac' if !$search_context || $search_context ne 'intranet';
+ my ($is_opac, $hidelostitems);
+ if ($search_context eq 'opac') {
+ $hidelostitems = C4::Context->preference('hidelostitems');
+ $is_opac = 1;
+ }
#Build branchnames hash
#find branchname
my $marcflavour = C4::Context->preference("marcflavour");
# We get the biblionumber position in MARC
my ($bibliotag,$bibliosubf)=GetMarcFromKohaField('biblio.biblionumber','');
- my $fw;
# loop through all of the records we've retrieved
for ( my $i = $offset ; $i <= $times - 1 ; $i++ ) {
- my $marcrecord = MARC::File::USMARC::decode( $marcresults[$i] );
- $fw = $scan
+ my $marcrecord = MARC::File::USMARC::decode( $marcresults->[$i] );
+ my $fw = $scan
? undef
: $bibliotag < 10
? GetFrameworkCode($marcrecord->field($bibliotag)->data)
# Pull out the items fields
my @fields = $marcrecord->field($itemtag);
+ my $marcflavor = C4::Context->preference("marcflavour");
+ # adding linked items that belong to host records
+ my $analyticsfield = '773';
+ if ($marcflavor eq 'MARC21' || $marcflavor eq 'NORMARC') {
+ $analyticsfield = '773';
+ } elsif ($marcflavor eq 'UNIMARC') {
+ $analyticsfield = '461';
+ }
+ foreach my $hostfield ( $marcrecord->field($analyticsfield)) {
+ my $hostbiblionumber = $hostfield->subfield("0");
+ my $linkeditemnumber = $hostfield->subfield("9");
+ if(!$hostbiblionumber eq undef){
+ my $hostbiblio = GetMarcBiblio($hostbiblionumber, 1);
+ my ($itemfield, undef) = GetMarcFromKohaField( 'items.itemnumber', GetFrameworkCode($hostbiblionumber) );
+ if(!$hostbiblio eq undef){
+ my @hostitems = $hostbiblio->field($itemfield);
+ foreach my $hostitem (@hostitems){
+ if ($hostitem->subfield("9") eq $linkeditemnumber){
+ my $linkeditem =$hostitem;
+ # append linked items if they exist
+ if (!$linkeditem eq undef){
+ push (@fields, $linkeditem);}
+ }
+ }
+ }
+ }
+ }
# Setting item statuses for display
my @available_items_loop;
my $other_count = 0;
my $wthdrawn_count = 0;
my $itemlost_count = 0;
+ my $hideatopac_count = 0;
my $itembinding_count = 0;
my $itemdamaged_count = 0;
my $item_in_transit_count = 0;
my $can_place_holds = 0;
- my $item_onhold_count = 0;
+ my $item_onhold_count = 0;
my $items_count = scalar(@fields);
- my $maxitems =
- ( C4::Context->preference('maxItemsinSearchResults') )
- ? C4::Context->preference('maxItemsinSearchResults') - 1
- : 1;
+ my $maxitems_pref = C4::Context->preference('maxItemsinSearchResults');
+ my $maxitems = $maxitems_pref ? $maxitems_pref - 1 : 1;
# loop through every item
+ my @hiddenitems;
foreach my $field (@fields) {
my $item;
}
# Hidden items
- my @items = ($item);
- my (@hiddenitems) = GetHiddenItemnumbers(@items);
- $item->{'hideatopac'} = 1 if (@hiddenitems);
+ if ($is_opac) {
+ my @hi = GetHiddenItemnumbers($item);
+ $item->{'hideatopac'} = @hi;
+ push @hiddenitems, @hi;
+ }
my $hbranch = C4::Context->preference('HomeOrHoldingBranch') eq 'homebranch' ? 'homebranch' : 'holdingbranch';
my $otherbranch = C4::Context->preference('HomeOrHoldingBranch') eq 'homebranch' ? 'holdingbranch' : 'homebranch';
my ($transfertfrom, $transfertto);
# is item on the reserve shelf?
- my $reservestatus = 0;
+ my $reservestatus = '';
my $reserveitem;
unless ($item->{wthdrawn}
# should map transit status to record indexed in Zebra.
#
($transfertwhen, $transfertfrom, $transfertto) = C4::Circulation::GetTransfers($item->{itemnumber});
- ($reservestatus, $reserveitem) = C4::Reserves::CheckReserves($item->{itemnumber});
+ ($reservestatus, $reserveitem, undef) = C4::Reserves::CheckReserves($item->{itemnumber});
}
- # item is withdrawn, lost or damaged
+ # item is withdrawn, lost, damaged, not for loan, reserved or in transit
if ( $item->{wthdrawn}
|| $item->{itemlost}
|| $item->{damaged}
$wthdrawn_count++ if $item->{wthdrawn};
$itemlost_count++ if $item->{itemlost};
$itemdamaged_count++ if $item->{damaged};
+ $hideatopac_count++ if $item->{hideatopac};
$item_in_transit_count++ if $transfertwhen ne '';
$item_onhold_count++ if $reservestatus eq 'Waiting';
$item->{status} = $item->{wthdrawn} . "-" . $item->{itemlost} . "-" . $item->{damaged} . "-" . $item->{notforloan};
+
+ # can place hold on item ?
+ if ((!$item->{damaged} || C4::Context->preference('AllowHoldsOnDamagedItems'))
+ && !$item->{itemlost}
+ && !$item->{withdrawn}
+ ) {
+ $can_place_holds = 1;
+ }
+
$other_count++;
my $key = $prefix . $item->{status};
}
}
} # notforloan, item level and biblioitem level
+ if ($items_count > 0) {
+ next if $is_opac && $hideatopac_count >= $items_count;
+ next if $hidelostitems && $itemlost_count >= $items_count;
+ }
my ( $availableitemscount, $onloanitemscount, $otheritemscount );
- $maxitems =
- ( C4::Context->preference('maxItemsinSearchResults') )
- ? C4::Context->preference('maxItemsinSearchResults') - 1
- : 1;
for my $key ( sort keys %$onloan_items ) {
(++$onloanitemscount > $maxitems) and last;
push @onloan_items_loop, $onloan_items->{$key};
use C4::Charset;
SetUTF8Flag($marcrecord);
$debug && warn $marcrecord->as_formatted;
- if (!$scan && $search_context eq 'opac' && C4::Context->preference("OPACXSLTResultsDisplay")) {
- # FIXME note that XSLTResultsDisplay (use of XSLT to format staff interface bib search results)
- # is not implemented yet
- $oldbiblio->{XSLTResultsRecord} = XSLTParse4Display($oldbiblio->{biblionumber}, $marcrecord, 'Results',
- $search_context, 1);
- # the last parameter tells Koha to clean up the problematic ampersand entities that Zebra outputs
-
+ my $interface = $search_context eq 'opac' ? 'OPAC' : '';
+ if (!$scan && C4::Context->preference($interface . "XSLTResultsDisplay")) {
+ $oldbiblio->{XSLTResultsRecord} = XSLTParse4Display($oldbiblio->{biblionumber}, $marcrecord, 'Results',
+ $search_context, 1, \@hiddenitems);
+ # the last parameter tells Koha to clean up the problematic ampersand entities that Zebra outputs
}
# if biblio level itypes are used and itemtype is notforloan, it can't be reserved either
$oldbiblio->{intransitcount} = $item_in_transit_count;
$oldbiblio->{onholdcount} = $item_onhold_count;
$oldbiblio->{orderedcount} = $ordered_count;
- $oldbiblio->{isbn} =~
- s/-//g; # deleting - in isbn to enable amazon content
+ # deleting - in isbn to enable amazon content
+ $oldbiblio->{isbn} =~ s/-//g;
if (C4::Context->preference("AlternateHoldingsField") && $items_count == 0) {
my $fieldspec = C4::Context->preference("AlternateHoldingsField");
$oldbiblio->{'alternateholdings_count'} = $alternateholdingscount;
}
- push( @newresults, $oldbiblio )
- if(not $hidelostitems
- or (($items_count > $itemlost_count )
- && $hidelostitems));
+ push( @newresults, $oldbiblio );
}
return @newresults;
sub z3950_search_args {
my $bibrec = shift;
- $bibrec = { title => $bibrec } if !ref $bibrec;
+ my $isbn = Business::ISBN->new($bibrec);
+
+ if (defined $isbn && $isbn->is_valid)
+ {
+ $bibrec = { isbn => $bibrec } if !ref $bibrec;
+ }
+ else {
+ $bibrec = { title => $bibrec } if !ref $bibrec;
+ }
my $array = [];
for my $field (qw/ lccn isbn issn title author dewey subject /)
{
return $array;
}
-=head2 BiblioAddAuthorities
-
-( $countlinked, $countcreated ) = BiblioAddAuthorities($record, $frameworkcode);
-
-this function finds the authorities linked to the biblio
- * search in the authority DB for the same authid (in $9 of the biblio)
- * search in the authority DB for the same 001 (in $3 of the biblio in UNIMARC)
- * search in the authority DB for the same values (exactly) (in all subfields of the biblio)
-OR adds a new authority record
-
-=over 2
-
-=item C<input arg:>
-
- * $record is the MARC record in question (marc blob)
- * $frameworkcode is the bibliographic framework to use (if it is "" it uses the default framework)
-
-=item C<Output arg:>
-
- * $countlinked is the number of authorities records that are linked to this authority
- * $countcreated
-
-=item C<BUGS>
- * I had to add this to Search.pm (instead of the logical Biblio.pm) because of a circular dependency (this sub uses SimpleSearch, and Search.pm uses Biblio.pm)
-
-=back
-
-=cut
-
-
-sub BiblioAddAuthorities{
- my ( $record, $frameworkcode ) = @_;
- my $dbh=C4::Context->dbh;
- my $query=$dbh->prepare(qq|
-SELECT authtypecode,tagfield
-FROM marc_subfield_structure
-WHERE frameworkcode=?
-AND (authtypecode IS NOT NULL AND authtypecode<>\"\")|);
-# SELECT authtypecode,tagfield
-# FROM marc_subfield_structure
-# WHERE frameworkcode=?
-# AND (authtypecode IS NOT NULL OR authtypecode<>\"\")|);
- $query->execute($frameworkcode);
- my ($countcreated,$countlinked);
- while (my $data=$query->fetchrow_hashref){
- foreach my $field ($record->field($data->{tagfield})){
- next if ($field->subfield('3')||$field->subfield('9'));
- # No authorities id in the tag.
- # Search if there is any authorities to link to.
- my $query='at='.$data->{authtypecode}.' ';
- map {$query.= ' and he,ext="'.$_->[1].'"' if ($_->[0]=~/[A-z]/)} $field->subfields();
- my ($error, $results, $total_hits)=SimpleSearch( $query, undef, undef, [ "authorityserver" ] );
- # there is only 1 result
- if ( $error ) {
- warn "BIBLIOADDSAUTHORITIES: $error";
- return (0,0) ;
- }
- if ( @{$results} == 1 ) {
- my $marcrecord = MARC::File::USMARC::decode($results->[0]);
- $field->add_subfields('9'=>$marcrecord->field('001')->data);
- $countlinked++;
- } elsif ( @{$results} > 1 ) {
- #More than One result
- #This can comes out of a lack of a subfield.
-# my $marcrecord = MARC::File::USMARC::decode($results->[0]);
-# $record->field($data->{tagfield})->add_subfields('9'=>$marcrecord->field('001')->data);
- $countlinked++;
- } else {
- #There are no results, build authority record, add it to Authorities, get authid and add it to 9
- ###NOTICE : This is only valid if a subfield is linked to one and only one authtypecode
- ###NOTICE : This can be a problem. We should also look into other types and rejected forms.
- my $authtypedata=C4::AuthoritiesMarc::GetAuthType($data->{authtypecode});
- next unless $authtypedata;
- my $marcrecordauth=MARC::Record->new();
- my $authfield=MARC::Field->new($authtypedata->{auth_tag_to_report},'','',"a"=>"".$field->subfield('a'));
- map { $authfield->add_subfields($_->[0]=>$_->[1]) if ($_->[0]=~/[A-z]/ && $_->[0] ne "a" )} $field->subfields();
- $marcrecordauth->insert_fields_ordered($authfield);
-
- # bug 2317: ensure new authority knows it's using UTF-8; currently
- # only need to do this for MARC21, as MARC::Record->as_xml_record() handles
- # automatically for UNIMARC (by not transcoding)
- # FIXME: AddAuthority() instead should simply explicitly require that the MARC::Record
- # use UTF-8, but as of 2008-08-05, did not want to introduce that kind
- # of change to a core API just before the 3.0 release.
- if (C4::Context->preference('marcflavour') eq 'MARC21') {
- SetMarcUnicodeFlag($marcrecordauth, 'MARC21');
- }
-
-# warn "AUTH RECORD ADDED : ".$marcrecordauth->as_formatted;
-
- my $authid=AddAuthority($marcrecordauth,'',$data->{authtypecode});
- $countcreated++;
- $field->add_subfields('9'=>$authid);
- }
- }
- }
- return ($countlinked,$countcreated);
-}
-
=head2 GetDistinctValues($field);
C<$field> is a reference to the fields array