X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=C4%2FSearch.pm;h=a3ffc091189c04f05d467357070893e76efc3df7;hb=a201a8bd898bb009baa54ce029ea0694e25f4e1d;hp=eb97daad371af79310ff1ba9742ceac70dc7cc66;hpb=600b47b08f73627b702b1d53df53cf36f9140bcb;p=koha_fer diff --git a/C4/Search.pm b/C4/Search.pm index eb97daad37..a3ffc09118 100644 --- a/C4/Search.pm +++ b/C4/Search.pm @@ -24,6 +24,7 @@ use Lingua::Stem; use C4::Search::PazPar2; use XML::Simple; use C4::Dates qw(format_date); +use C4::XSLT; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $DEBUG); @@ -157,7 +158,7 @@ sub FindDuplicate { =head2 SimpleSearch -($error,$results) = SimpleSearch($query,@servers); +($error,$results) = SimpleSearch( $query, $offset, $max_results, [ @servers ] ); This function provides a simple search API on the bibliographic catalog @@ -167,6 +168,9 @@ This function provides a simple search API on the bibliographic catalog * $query can be a simple keyword or a complete CCL query * @servers is optional. Defaults to biblioserver as found in koha-conf.xml + * $offset - If present, represents the number of records at the beggining to omit. Defaults to 0 + * $max_results - if present, determines the maximum number of records to fetch. undef is All. defaults to undef. + =item C * $error is a empty unless an error is detected @@ -210,7 +214,8 @@ $template->param(result=>\@results); =cut sub SimpleSearch { - my $query = shift; + my ( $query, $offset, $max_results, $servers ) = @_; + if ( C4::Context->preference('NoZebra') ) { my $result = NZorder( NZanalyse($query) )->{'biblioserver'}; my $search_result = @@ -219,15 +224,13 @@ sub SimpleSearch { return ( undef, $search_result ); } else { - my @servers = @_; + # FIXME hardcoded value. See catalog/search.pl & opac-search.pl too. + my @servers = defined ( $servers ) ? @$servers : ( "biblioserver" ); my @results; my @tmpresults; my @zconns; return ( "No query entered", undef ) unless $query; - # FIXME hardcoded value. See catalog/search.pl & opac-search.pl too. - @servers = ("biblioserver") unless @servers; - # Initialize & Search Zebra for ( my $i = 0 ; $i < @servers ; $i++ ) { eval { @@ -257,21 +260,25 @@ sub SimpleSearch { return ( $error, undef ); } } - my $hits = 0; - my $ev; + while ( ( my $i = ZOOM::event( \@zconns ) ) != 0 ) { - $ev = $zconns[ $i - 1 ]->last_event(); - if ( $ev == ZOOM::Event::ZEND ) { - $hits = $tmpresults[ $i - 1 ]->size(); - } - if ( $hits > 0 ) { - for ( my $j = 0 ; $j < $hits ; $j++ ) { - my $record = $tmpresults[ $i - 1 ]->record($j)->raw(); + my $event = $zconns[ $i - 1 ]->last_event(); + if ( $event == ZOOM::Event::ZEND ) { + + my $first_record = defined( $offset ) ? $offset+1 : 1; + my $hits = $tmpresults[ $i - 1 ]->size(); + my $last_record = $hits; + if ( defined $max_results && $offset + $max_results < $hits ) { + $last_record = $offset + $max_results; + } + + for my $j ( $first_record..$last_record ) { + my $record = $tmpresults[ $i - 1 ]->record( $j-1 )->raw(); # 0 indexed push @results, $record; } } - $hits = 0; } + return ( undef, \@results ); } } @@ -852,9 +859,7 @@ See verbose embedded documentation. sub buildQuery { my ( $operators, $operands, $indexes, $limits, $sort_by, $scan ) = @_; - warn "---------" if $DEBUG; - warn "Enter buildQuery" if $DEBUG; - warn "---------" if $DEBUG; + warn "---------\nEnter buildQuery\n---------" if $DEBUG; # dereference my @operators = @$operators if $operators; @@ -962,10 +967,19 @@ sub buildQuery { $remove_stopwords ) = ( 0, 0, 0, 0, 0 ); } + # 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, + $remove_stopwords + ) = ( 0, 0, 0, 0, 0 ); + } # Set default structure attribute (word list) my $struct_attr; - unless ( !$index || $index =~ /(st-|phr|ext|wrdl)/ ) { + unless ( $indexes_set || !$index || $index =~ /(st-|phr|ext|wrdl)/ ) { $struct_attr = ",wrdl"; } @@ -1157,9 +1171,7 @@ sub buildQuery { warn "LIMIT:" . $limit; warn "LIMIT CGI:" . $limit_cgi; warn "LIMIT DESC:" . $limit_desc; - warn "---------"; - warn "Leave buildQuery"; - warn "---------"; + warn "---------\nLeave buildQuery\n---------"; } return ( undef, $query, $simple_query, $query_cgi, @@ -1179,7 +1191,6 @@ Format results in a form suitable for passing to the template sub searchResults { my ( $searchdesc, $hits, $results_per_page, $offset, @marcresults ) = @_; my $dbh = C4::Context->dbh; - my $toggle; my $even = 1; my @newresults; @@ -1201,15 +1212,13 @@ sub searchResults { while ( my $bdata = $bsth->fetchrow_hashref ) { $branches{ $bdata->{'branchcode'} } = $bdata->{'branchname'}; } - my %locations; - my $lsch = - $dbh->prepare( -"SELECT authorised_value,lib FROM authorised_values WHERE category = 'LOC'" - ); - $lsch->execute(); - while ( my $ldata = $lsch->fetchrow_hashref ) { - $locations{ $ldata->{'authorised_value'} } = $ldata->{'lib'}; - } +# FIXME - We build an authorised values hash here, using the default framework +# though it is possible to have different authvals for different fws. + + my $shelflocations =GetKohaAuthorisedValues('items.location',''); + + # get notforloan authorised value list (see $shelflocations FIXME) + my $notforloan_authorised_value = GetAuthValCode('items.notforloan',''); #Build itemtype hash #find itemtype & itemtype image @@ -1236,14 +1245,6 @@ sub searchResults { $sth->execute; my ($itemtag) = $sth->fetchrow; - # get notforloan authorised value list - $sth = - $dbh->prepare( -"SELECT authorised_value FROM `marc_subfield_structure` WHERE kohafield = 'items.notforloan' AND frameworkcode=''" - ); - $sth->execute; - my ($notforloan_authorised_value) = $sth->fetchrow; - ## find column names of items related to MARC my $sth2 = $dbh->prepare("SHOW COLUMNS FROM items"); $sth2->execute; @@ -1285,7 +1286,9 @@ sub searchResults { $oldbiblio->{description} = $itemtypes{ $oldbiblio->{itemtype} }->{description}; } - + my $aisbn=$oldbiblio->{'isbn'}; + $aisbn =~ /(\d*[X]*)/; + $oldbiblio->{'amazonisbn'} = $1; # Build summary if there is one (the summary is defined in the itemtypes table) # FIXME: is this used anywhere, I think it can be commented out? -- JF if ( $itemtypes{ $oldbiblio->{itemtype} }->{summary} ) { @@ -1313,7 +1316,10 @@ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g; $oldbiblio->{summary} = $summary; } -# Add search-term highlighting to the whole record where they match using s + # save an author with no tag, for the > link + $oldbiblio->{'author_nospan'} = $oldbiblio->{'author'}; + $oldbiblio->{'title_nospan'} = $oldbiblio->{'title'}; + # Add search-term highlighting to the whole record where they match using s if (C4::Context->preference("OpacHighlightedWords")){ my $searchhighlightblob; for my $highlight_field ( $marcrecord->fields ) { @@ -1336,43 +1342,33 @@ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g; } $searchhighlightblob = ' ... '.$searchhighlightblob if $searchhighlightblob; $oldbiblio->{'searchhighlightblob'} = $searchhighlightblob; - } -# save an author with no tag, for the > link - $oldbiblio->{'author_nospan'} = $oldbiblio->{'author'}; - - # Add search-term highlighting to the title, subtitle, etc. fields - for my $term ( keys %$span_terms_hashref ) { - my $old_term = $term; - if ( length($term) > 3 ) { - $term =~ s/(.*=|\)|\(|\+|\.|\?|\[|\]|\\|\*)//g; - $oldbiblio->{'title'} =~ - s/$term/$&<\/span>/gi; - $oldbiblio->{'subtitle'} =~ - s/$term/$&<\/span>/gi; - $oldbiblio->{'author'} =~ - s/$term/$&<\/span>/gi; - $oldbiblio->{'publishercode'} =~ - s/$term/$&<\/span>/gi; - $oldbiblio->{'place'} =~ - s/$term/$&<\/span>/gi; - $oldbiblio->{'pages'} =~ - s/$term/$&<\/span>/gi; - $oldbiblio->{'notes'} =~ - s/$term/$&<\/span>/gi; - $oldbiblio->{'size'} =~ - s/$term/$&<\/span>/gi; + + # Add search-term highlighting to the title, subtitle, etc. fields + for my $term ( keys %$span_terms_hashref ) { + my $old_term = $term; + if ( length($term) > 3 ) { + $term =~ s/(.*=|\)|\(|\+|\.|\?|\[|\]|\\|\*)//g; + $oldbiblio->{'title'} =~ + s/$term/$&<\/span>/gi; + $oldbiblio->{'subtitle'} =~ + s/$term/$&<\/span>/gi; + $oldbiblio->{'author'} =~ + s/$term/$&<\/span>/gi; + $oldbiblio->{'publishercode'} =~ + s/$term/$&<\/span>/gi; + $oldbiblio->{'place'} =~ + s/$term/$&<\/span>/gi; + $oldbiblio->{'pages'} =~ + s/$term/$&<\/span>/gi; + $oldbiblio->{'notes'} =~ + s/$term/$&<\/span>/gi; + $oldbiblio->{'size'} =~ + s/$term/$&<\/span>/gi; + } } } - # FIXME: - # surely there's a better way to handle this - if ( $i % 2 ) { - $toggle = "#ffffcc"; - } - else { - $toggle = "white"; - } - $oldbiblio->{'toggle'} = $toggle; + ($i % 2) and $oldbiblio->{'toggle'} = 1; # Pull out the items fields my @fields = $marcrecord->field($itemtag); @@ -1430,7 +1426,7 @@ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g; $onloan_items->{$key}->{due_date} = format_date($item->{onloan}); $onloan_items->{$key}->{count}++ if $item->{homebranch}; $onloan_items->{$key}->{branchname} = $item->{branchname}; - $onloan_items->{$key}->{location} = $locations{ $item->{location} }; + $onloan_items->{$key}->{location} = $shelflocations->{ $item->{location} }; $onloan_items->{$key}->{itemcallnumber} = $item->{itemcallnumber}; $onloan_items->{$key}->{imageurl} = getitemtypeimagesrc() . "/" . $itemtypes{ $item->{itype} }->{imageurl}; # if something's checked out and lost, mark it as 'long overdue' @@ -1468,7 +1464,7 @@ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g; } $other_items->{$key}->{notforloan} = GetAuthorisedValueDesc('','',$item->{notforloan},'','',$notforloan_authorised_value) if $notforloan_authorised_value; $other_items->{$key}->{count}++ if $item->{homebranch}; - $other_items->{$key}->{location} = $locations{ $item->{location} }; + $other_items->{$key}->{location} = $shelflocations->{ $item->{location} }; $other_items->{$key}->{imageurl} = getitemtypeimagesrc() . "/" . $itemtypes{ $item->{itype} }->{imageurl}; } # item is available @@ -1479,7 +1475,7 @@ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g; foreach (qw(branchname itemcallnumber)) { $available_items->{$prefix}->{$_} = $item->{$_}; } - $available_items->{$prefix}->{location} = $locations{ $item->{location} }; + $available_items->{$prefix}->{location} = $shelflocations->{ $item->{location} }; $available_items->{$prefix}->{imageurl} = getitemtypeimagesrc() . "/" . $itemtypes{ $item->{itype} }->{imageurl}; } } @@ -1490,22 +1486,25 @@ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g; ? C4::Context->preference('maxItemsinSearchResults') - 1 : 1; for my $key ( sort keys %$onloan_items ) { - $onloanitemscount++; - push @onloan_items_loop, $onloan_items->{$key} - unless $onloanitemscount > $maxitems; + (++$onloanitemscount > $maxitems) and last; + push @onloan_items_loop, $onloan_items->{$key}; } for my $key ( sort keys %$other_items ) { - $otheritemscount++; - push @other_items_loop, $other_items->{$key} - unless $otheritemscount > $maxitems; + (++$otheritemscount > $maxitems) and last; + push @other_items_loop, $other_items->{$key}; } for my $key ( sort keys %$available_items ) { - $availableitemscount++; + (++$availableitemscount > $maxitems) and last; push @available_items_loop, $available_items->{$key} - unless $availableitemscount > $maxitems; } -# last check for norequest : if itemtype is notforloan, it can't be reserved either, whatever the items + # XSLT processing of some stuff + if (C4::Context->preference("XSLTResultsDisplay") ) { + my $newxmlrecord = XSLTParse4Display($oldbiblio->{biblionumber},C4::Context->config('opachtdocs')."/prog/en/xslt/MARC21slim2OPACResults.xsl"); + $oldbiblio->{XSLTResultsRecord} = $newxmlrecord; + } + + # 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}; $oldbiblio->{norequests} = 1 unless $can_place_holds; @@ -1775,9 +1774,7 @@ sub NZanalyse { warn "return : $results for LEAF : $string" if $DEBUG; return $results; } - warn "---------" if $DEBUG; - warn "Leave NZanalyse" if $DEBUG; - warn "---------" if $DEBUG; + warn "---------\nLeave NZanalyse\n---------" if $DEBUG; } sub NZoperatorAND{