X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=C4%2FSearch.pm;h=fdb34790a37b13fe623c2ba018c6159ec71d1e0c;hb=0352a8f24ac72b7dfbf84ea3c6f11e2e714708b0;hp=45ebb24b0349bf09ed5721891e884bc9b41bce76;hpb=87ec4126484d5c55efd66b359220934d3501ff6c;p=koha_gimpoz diff --git a/C4/Search.pm b/C4/Search.pm index 45ebb24b03..fdb34790a3 100644 --- a/C4/Search.pm +++ b/C4/Search.pm @@ -25,10 +25,13 @@ use Lingua::Stem; use C4::Search::PazPar2; use XML::Simple; use C4::Dates qw(format_date); +use C4::Members qw(GetHideLostItemsPreference); use C4::XSLT; use C4::Branch; use C4::Reserves; # CheckReserves use C4::Debug; +use C4::Items; +use YAML; use URI::Escape; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $DEBUG); @@ -120,18 +123,19 @@ sub FindDuplicate { } } - # FIXME: add error handling - my ( $error, $searchresults ) = SimpleSearch($query); # FIXME :: hardcoded ! + my ( $error, $searchresults, undef ) = SimpleSearch($query); # FIXME :: hardcoded ! my @results; - foreach my $possible_duplicate_record (@$searchresults) { - my $marcrecord = - MARC::Record->new_from_usmarc($possible_duplicate_record); - my $result = TransformMarcToKoha( $dbh, $marcrecord, '' ); - - # FIXME :: why 2 $biblionumber ? - if ($result) { - push @results, $result->{'biblionumber'}; - push @results, $result->{'title'}; + if (!defined $error) { + foreach my $possible_duplicate_record (@{$searchresults}) { + my $marcrecord = + MARC::Record->new_from_usmarc($possible_duplicate_record); + my $result = TransformMarcToKoha( $dbh, $marcrecord, '' ); + + # FIXME :: why 2 $biblionumber ? + if ($result) { + push @results, $result->{'biblionumber'}; + push @results, $result->{'title'}; + } } } return @results; @@ -153,12 +157,16 @@ This function provides a simple search API on the bibliographic catalog * $max_results - if present, determines the maximum number of records to fetch. undef is All. defaults to undef. -=item C +=item C - * $error is a empty unless an error is detected - * \@results is an array of records. + Returns an array consisting of three elements + * $error is undefined unless an error is detected + * $results is a reference to an array of records. * $total_hits is the number of hits that would have been returned with no limit + If an error is returned the two other return elements are undefined. If error itself is undefined + the other two elements are always defined + =item C =back @@ -172,23 +180,23 @@ if (defined $error) { exit; } -my $hits = scalar @$marcresults; +my $hits = @{$marcresults}; my @results; -for my $i (0..$hits) { - my %resultsloop; - my $marcrecord = MARC::File::USMARC::decode($marcresults->[$i]); - my $biblio = TransformMarcToKoha(C4::Context->dbh,$marcrecord,''); - - #build the hash for the template. - $resultsloop{title} = $biblio->{'title'}; - $resultsloop{subtitle} = $biblio->{'subtitle'}; - $resultsloop{biblionumber} = $biblio->{'biblionumber'}; - $resultsloop{author} = $biblio->{'author'}; - $resultsloop{publishercode} = $biblio->{'publishercode'}; - $resultsloop{publicationyear} = $biblio->{'publicationyear'}; +for my $r ( @{$marcresults} ) { + my $marcrecord = MARC::File::USMARC::decode($r); + my $biblio = TransformMarcToKoha(C4::Context->dbh,$marcrecord,q{}); + + #build the iarray of hashs for the template. + push @results, { + title => $biblio->{'title'}, + subtitle => $biblio->{'subtitle'}, + biblionumber => $biblio->{'biblionumber'}, + author => $biblio->{'author'}, + publishercode => $biblio->{'publishercode'}, + publicationyear => $biblio->{'publicationyear'}, + }; - push @results, \%resultsloop; } $template->param(result=>\@results); @@ -206,14 +214,14 @@ sub SimpleSearch { return ( undef, $search_result, scalar($result->{hits}) ); } else { + return ( 'No query entered', undef, undef ) unless $query; # FIXME hardcoded value. See catalog/search.pl & opac-search.pl too. - my @servers = defined ( $servers ) ? @$servers : ( "biblioserver" ); - my @results; + my @servers = defined ( $servers ) ? @$servers : ( 'biblioserver' ); my @zoom_queries; my @tmpresults; my @zconns; - my $total_hits; - return ( "No query entered", undef, undef ) unless $query; + my $results = []; + my $total_hits = 0; # Initialize & Search Zebra for ( my $i = 0 ; $i < @servers ; $i++ ) { @@ -257,7 +265,7 @@ sub SimpleSearch { for my $j ( $first_record..$last_record ) { my $record = $tmpresults[ $i - 1 ]->record( $j-1 )->raw(); # 0 indexed - push @results, $record; + push @{$results}, $record; } } } @@ -269,7 +277,7 @@ sub SimpleSearch { $zoom_query->destroy(); } - return ( undef, \@results, $total_hits ); + return ( undef, $results, $total_hits ); } } @@ -309,6 +317,7 @@ sub getRecords { my $facets_counter = (); my $facets_info = (); my $facets = getFacets(); + my $facets_maxrecs = C4::Context->preference('maxRecordsForFacets')||20; my @facets_loop; # stores the ref to array of hashes for template facets loop @@ -350,10 +359,10 @@ sub getRecords { # Note: sort will override rank my $sort_by; foreach my $sort (@sort_by) { - if ( $sort eq "author_az" ) { + if ( $sort eq "author_az" || $sort eq "author_asc" ) { $sort_by .= "1=1003 sort( "yaz", $sort_by ) < 0 ) { warn "WARNING sort $sort_by failed"; } @@ -418,7 +427,6 @@ sub getRecords { for ( my $j = $offset ; $j < $times ; $j++ ) { my $records_hash; my $record; - my $facet_record; ## Check if it's an index scan if ($scan) { @@ -451,33 +459,55 @@ sub getRecords { # warn "RECORD $j:".$record; $results_hash->{'RECORDS'}[$j] = $record; - - # Fill the facets while we're looping, but only for the biblioserver - $facet_record = MARC::Record->new_from_usmarc($record) - if $servers[ $i - 1 ] =~ /biblioserver/; - - #warn $servers[$i-1]."\n".$record; #.$facet_record->title(); - if ($facet_record) { - for ( my $k = 0 ; $k <= @$facets ; $k++ ) { - ($facets->[$k]) or next; - my @fields = map {$facet_record->field($_)} @{$facets->[$k]->{'tags'}} ; - for my $field (@fields) { - my @subfields = $field->subfields(); - for my $subfield (@subfields) { - my ( $code, $data ) = @$subfield; - ($code eq $facets->[$k]->{'subfield'}) or next; - $facets_counter->{ $facets->[$k]->{'link_value'} }->{$data}++; - } - } - $facets_info->{ $facets->[$k]->{'link_value'} }->{'label_value'} = - $facets->[$k]->{'label_value'}; - $facets_info->{ $facets->[$k]->{'link_value'} }->{'expanded'} = - $facets->[$k]->{'expanded'}; - } - } } + } $results_hashref->{ $servers[ $i - 1 ] } = $results_hash; + + # Fill the facets while we're looping, but only for the biblioserver and not for a scan + if ( !$scan && $servers[ $i - 1 ] =~ /biblioserver/ ) { + + my $jmax = $size>$facets_maxrecs? $facets_maxrecs: $size; + + for ( my $k = 0 ; $k <= @$facets ; $k++ ) { + ($facets->[$k]) or next; + my @fcodes = @{$facets->[$k]->{'tags'}}; + my $sfcode = $facets->[$k]->{'subfield'}; + + for ( my $j = 0 ; $j < $jmax ; $j++ ) { + my $render_record = $results[ $i - 1 ]->record($j)->render(); + my @used_datas = (); + + foreach my $fcode (@fcodes) { + + # avoid first line + my $field_pattern = '\n'.$fcode.' ([^\n]+)'; + my @field_tokens = ( $render_record =~ /$field_pattern/g ) ; + + foreach my $field_token (@field_tokens) { + my $subfield_pattern = '\$'.$sfcode.' ([^\$]+)'; + my @subfield_values = ( $field_token =~ /$subfield_pattern/g ); + + foreach my $subfield_value (@subfield_values) { + + my $data = $subfield_value; + $data =~ s/^\s+//; # trim left + $data =~ s/\s+$//; # trim right + + unless ( $data ~~ @used_datas ) { + $facets_counter->{ $facets->[$k]->{'link_value'} }->{$data}++; + push @used_datas, $data; + } + } # subfields + } # fields + } # field codes + } # records + + $facets_info->{ $facets->[$k]->{'link_value'} }->{'label_value'} = $facets->[$k]->{'label_value'}; + $facets_info->{ $facets->[$k]->{'link_value'} }->{'expanded'} = $facets->[$k]->{'expanded'}; + } # facets + } + # End PROGILONE } # warn "connection ", $i-1, ": $size hits"; @@ -511,9 +541,11 @@ sub getRecords { # fix the length that will display in the label, my $facet_label_value = $one_facet; + my $facet_max_length = + C4::Context->preference('FacetLabelTruncationLength') || 20; $facet_label_value = - substr( $one_facet, 0, 20 ) . "..." - unless length($facet_label_value) <= 20; + substr( $one_facet, 0, $facet_max_length ) . "..." + if length($facet_label_value) > $facet_max_length; # if it's a branch, label by the name, not the code, if ( $link_value =~ /branch/ ) { @@ -810,6 +842,7 @@ sub getIndexes{ 'Authority-Number', 'authtype', 'bc', + 'Bib-level', 'biblionumber', 'bio', 'biography', @@ -840,6 +873,7 @@ sub getIndexes{ 'Date-of-acquisition', 'Date-of-publication', 'Dewey-classification', + 'EAN', 'extent', 'fic', 'fiction', @@ -855,7 +889,9 @@ sub getIndexes{ 'id-other', 'Illustration-code', 'ISBN', + 'isbn', 'ISSN', + 'issn', 'itemtype', 'kw', 'Koha-Auth-Number', @@ -874,12 +910,15 @@ sub getIndexes{ 'mc-itemtype', 'mc-rtype', 'mus', + 'name', + 'Music-number', 'Name-geographic', 'Name-geographic-heading', 'Name-geographic-see', 'Name-geographic-seealso', 'nb', 'Note', + 'notes', 'ns', 'nt', 'pb', @@ -914,6 +953,7 @@ sub getIndexes{ 'su-to', 'su-ut', 'ut', + 'UPC', 'Term-genre-form', 'Term-genre-form-heading', 'Term-genre-form-see', @@ -922,6 +962,7 @@ sub getIndexes{ 'Title', 'Title-cover', 'Title-series', + 'Title-host', 'Title-uniform', 'Title-uniform-heading', 'Title-uniform-see', @@ -964,6 +1005,8 @@ sub getIndexes{ 'reserves', 'restricted', 'stack', + 'stocknumber', + 'inv', 'uri', 'withdrawn', @@ -1029,15 +1072,14 @@ sub buildQuery { 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 @@ -1091,10 +1133,12 @@ sub buildQuery { my $indexes_set; # If the user is sophisticated enough to specify an index, turn off field weighting, stemming, and stopword handling - if ( $operands[$i] =~ /(:|=)/ || $scan ) { + if ( $operands[$i] =~ /\w(:|=)/ || $scan ) { $weight_fields = 0; $stemming = 0; $remove_stopwords = 0; + } else { + $operands[$i] =~ s/\?/{?}/g; # need to escape question marks } my $operand = $operands[$i]; my $index = $indexes[$i]; @@ -1115,7 +1159,6 @@ sub buildQuery { } # ISBN,ISSN,Standard Number, don't need special treatment elsif ( $index eq 'nb' || $index eq 'ns' ) { - $indexes_set++; ( $stemming, $auto_truncation, $weight_fields, $fuzzy_enabled, @@ -1130,7 +1173,7 @@ sub buildQuery { # Set default structure attribute (word list) my $struct_attr = q{}; - unless ( $indexes_set || !$index || $index =~ /(st-|phr|ext|wrdl)/ ) { + unless ( $indexes_set || !$index || $index =~ /(st-|phr|ext|wrdl|nb|ns)/ ) { $struct_attr = ",wrdl"; } @@ -1276,7 +1319,14 @@ sub buildQuery { # group_OR_limits, prefixed by mc- # OR every member of the group elsif ( $this_limit =~ /mc/ ) { -# if ( $this_limit =~ /mc/ ) { + + if ( $this_limit =~ /mc-ccode:/ ) { + # in case the mc-ccode value has complicating chars like ()'s inside it we wrap in quotes + $this_limit =~ tr/"//d; + my ($k,$v) = split(/:/, $this_limit,2); + $this_limit = $k.":\"".$v."\""; + } + $group_OR_limits .= " or " if $group_OR_limits; $limit_desc .= " or " if $group_OR_limits; $group_OR_limits .= "$this_limit"; @@ -1315,7 +1365,7 @@ sub buildQuery { # This is flawed , means we can't search anything with : in it # if user wants to do ccl or cql, start the query with that # $query =~ s/:/=/g; - $query =~ s/(?<=(ti|au|pb|su|an|kw|mc)):/=/g; + $query =~ s/(?<=(ti|au|pb|su|an|kw|mc|nb|ns)):/=/g; $query =~ s/(?<=(wrdl)):/=/g; $query =~ s/(?<=(trn|phr)):/=/g; $limit =~ s/:/=/g; @@ -1445,9 +1495,9 @@ sub searchResults { $oldbiblio->{result_number} = $i + 1; # add imageurl to itemtype if there is one - $oldbiblio->{imageurl} = getitemtypeimagelocation( 'opac', $itemtypes{ $oldbiblio->{itemtype} }->{imageurl} ); + $oldbiblio->{imageurl} = getitemtypeimagelocation( $search_context, $itemtypes{ $oldbiblio->{itemtype} }->{imageurl} ); - $oldbiblio->{'authorised_value_images'} = C4::Items::get_authorised_value_images( C4::Biblio::get_biblio_authorised_values( $oldbiblio->{'biblionumber'}, $marcrecord ) ); + $oldbiblio->{'authorised_value_images'} = ($search_context eq 'opac' && C4::Context->preference('AuthorisedValueImages')) || ($search_context eq 'intranet' && C4::Context->preference('StaffAuthorisedValueImages')) ? C4::Items::get_authorised_value_images( C4::Biblio::get_biblio_authorised_values( $oldbiblio->{'biblionumber'}, $marcrecord ) ) : []; $oldbiblio->{normalized_upc} = GetNormalizedUPC( $marcrecord,$marcflavour); $oldbiblio->{normalized_ean} = GetNormalizedEAN( $marcrecord,$marcflavour); $oldbiblio->{normalized_oclc} = GetNormalizedOCLCNumber($marcrecord,$marcflavour); @@ -1509,6 +1559,33 @@ sub searchResults { # 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; @@ -1546,8 +1623,14 @@ sub searchResults { $item->{$code} = $field->subfield( $subfieldstosearch{$code} ); } - my $hbranch = C4::Context->preference('HomeOrHoldingBranch') eq 'homebranch' ? 'homebranch' : 'holdingbranch'; - my $otherbranch = C4::Context->preference('HomeOrHoldingBranch') eq 'homebranch' ? 'holdingbranch' : 'homebranch'; + # Hidden items + my @items = ($item); + my (@hiddenitems) = GetHiddenItemnumbers(@items); + $item->{'hideatopac'} = 1 if (@hiddenitems); + + my $hbranch = C4::Context->preference('HomeOrHoldingBranch') eq 'homebranch' ? 'homebranch' : 'holdingbranch'; + my $otherbranch = C4::Context->preference('HomeOrHoldingBranch') eq 'homebranch' ? 'holdingbranch' : 'homebranch'; + # set item's branch name, use HomeOrHoldingBranch syspref first, fall back to the other one if ($item->{$hbranch}) { $item->{'branchname'} = $branches{$item->{$hbranch}}; @@ -1558,7 +1641,8 @@ sub searchResults { my $prefix = $item->{$hbranch} . '--' . $item->{location} . $item->{itype} . $item->{itemcallnumber}; # For each grouping of items (onloan, available, unavailable), we build a key to store relevant info about that item - if ( $item->{onloan} ) { + my $userenv = C4::Context->userenv; + if ( $item->{onloan} && !(C4::Members::GetHideLostItemsPreference($userenv->{'number'}) && $item->{itemlost}) ) { $onloan_count++; my $key = $prefix . $item->{onloan} . $item->{barcode}; $onloan_items->{$key}->{due_date} = format_date($item->{onloan}); @@ -1566,7 +1650,7 @@ sub searchResults { $onloan_items->{$key}->{branchname} = $item->{branchname}; $onloan_items->{$key}->{location} = $shelflocations->{ $item->{location} }; $onloan_items->{$key}->{itemcallnumber} = $item->{itemcallnumber}; - $onloan_items->{$key}->{imageurl} = getitemtypeimagelocation( 'opac', $itemtypes{ $item->{itype} }->{imageurl} ); + $onloan_items->{$key}->{imageurl} = getitemtypeimagelocation( $search_context, $itemtypes{ $item->{itype} }->{imageurl} ); # if something's checked out and lost, mark it as 'long overdue' if ( $item->{itemlost} ) { $onloan_items->{$prefix}->{longoverdue}++; @@ -1614,11 +1698,12 @@ sub searchResults { ($reservestatus, $reserveitem) = 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} || $item->{notforloan} > 0 + || $item->{hideatopac} || $reservestatus eq 'Waiting' || ($transfertwhen ne '')) { @@ -1628,29 +1713,38 @@ sub searchResults { $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}; - foreach (qw(wthdrawn itemlost damaged branchname itemcallnumber)) { - $other_items->{$key}->{$_} = $item->{$_}; - } - $other_items->{$key}->{intransit} = ($transfertwhen ne '') ? 1 : 0; + my $key = $prefix . $item->{status}; + foreach (qw(wthdrawn itemlost damaged branchname itemcallnumber hideatopac)) { + $other_items->{$key}->{$_} = $item->{$_}; + } + $other_items->{$key}->{intransit} = ( $transfertwhen ne '' ) ? 1 : 0; $other_items->{$key}->{onhold} = ($reservestatus) ? 1 : 0; $other_items->{$key}->{notforloan} = GetAuthorisedValueDesc('','',$item->{notforloan},'','',$notforloan_authorised_value) if $notforloan_authorised_value; $other_items->{$key}->{count}++ if $item->{$hbranch}; $other_items->{$key}->{location} = $shelflocations->{ $item->{location} }; - $other_items->{$key}->{imageurl} = getitemtypeimagelocation( 'opac', $itemtypes{ $item->{itype} }->{imageurl} ); + $other_items->{$key}->{imageurl} = getitemtypeimagelocation( $search_context, $itemtypes{ $item->{itype} }->{imageurl} ); } # item is available else { $can_place_holds = 1; $available_count++; $available_items->{$prefix}->{count}++ if $item->{$hbranch}; - foreach (qw(branchname itemcallnumber)) { + foreach (qw(branchname itemcallnumber hideatopac)) { $available_items->{$prefix}->{$_} = $item->{$_}; } $available_items->{$prefix}->{location} = $shelflocations->{ $item->{location} }; - $available_items->{$prefix}->{imageurl} = getitemtypeimagelocation( 'opac', $itemtypes{ $item->{itype} }->{imageurl} ); + $available_items->{$prefix}->{imageurl} = getitemtypeimagelocation( $search_context, $itemtypes{ $item->{itype} }->{imageurl} ); } } } # notforloan, item level and biblioitem level @@ -1680,12 +1774,17 @@ sub searchResults { # 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); + $search_context, 1); + # the last parameter tells Koha to clean up the problematic ampersand entities that Zebra outputs + } - # last check for norequest : if itemtype is notforloan, it can't be reserved either, whatever the items - $can_place_holds = 0 - if $itemtypes{ $oldbiblio->{itemtype} }->{notforloan}; + # if biblio level itypes are used and itemtype is notforloan, it can't be reserved either + if (!C4::Context->preference("item-level_itypes")) { + if ($itemtypes{ $oldbiblio->{itemtype} }->{notforloan}) { + $can_place_holds = 0; + } + } $oldbiblio->{norequests} = 1 unless $can_place_holds; $oldbiblio->{itemsplural} = 1 if $items_count > 1; $oldbiblio->{items_count} = $items_count; @@ -1706,6 +1805,35 @@ sub searchResults { $oldbiblio->{orderedcount} = $ordered_count; $oldbiblio->{isbn} =~ s/-//g; # deleting - in isbn to enable amazon content + + if (C4::Context->preference("AlternateHoldingsField") && $items_count == 0) { + my $fieldspec = C4::Context->preference("AlternateHoldingsField"); + my $subfields = substr $fieldspec, 3; + my $holdingsep = C4::Context->preference("AlternateHoldingsSeparator") || ' '; + my @alternateholdingsinfo = (); + my @holdingsfields = $marcrecord->field(substr $fieldspec, 0, 3); + my $alternateholdingscount = 0; + + for my $field (@holdingsfields) { + my %holding = ( holding => '' ); + my $havesubfield = 0; + for my $subfield ($field->subfields()) { + if ((index $subfields, $$subfield[0]) >= 0) { + $holding{'holding'} .= $holdingsep if (length $holding{'holding'} > 0); + $holding{'holding'} .= $$subfield[1]; + $havesubfield++; + } + } + if ($havesubfield) { + push(@alternateholdingsinfo, \%holding); + $alternateholdingscount++; + } + } + + $oldbiblio->{'ALTERNATEHOLDINGS'} = \@alternateholdingsinfo; + $oldbiblio->{'alternateholdings_count'} = $alternateholdingscount; + } + push( @newresults, $oldbiblio ) if(not $hidelostitems or (($items_count > $itemlost_count ) @@ -2194,7 +2322,7 @@ sub NZorder { # sort the hash and return the same structure as GetRecords (Zebra querying) my $result_hash; my $numbers = 0; - if ( $ordering eq 'author_za' ) { # sort by author desc + if ( $ordering eq 'author_za' || $ordering eq 'author_dsc' ) { # sort by author desc foreach my $key ( sort { $b cmp $a } ( keys %result ) ) { $result_hash->{'RECORDS'}[ $numbers++ ] = $result{$key}->as_usmarc(); @@ -2567,11 +2695,11 @@ AND (authtypecode IS NOT NULL AND authtypecode<>\"\")|); warn "BIBLIOADDSAUTHORITIES: $error"; return (0,0) ; } - if ($results && scalar(@$results)==1) { + if ( @{$results} == 1 ) { my $marcrecord = MARC::File::USMARC::decode($results->[0]); $field->add_subfields('9'=>$marcrecord->field('001')->data); $countlinked++; - } elsif (scalar(@$results)>1) { + } 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]);