X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FSearch.pm;h=d78f40731bb956f0403c49582b5366f1618ca3a1;hb=b450285003acf78223dfa96b34ca2a7799f778fe;hp=8499c0079fbaf1f864b56342227fee788615ecfa;hpb=0ef54684d1fe9ea47f622eeb28e04160fab49c7d;p=koha.git diff --git a/C4/Search.pm b/C4/Search.pm index 8499c0079f..d78f40731b 100644 --- a/C4/Search.pm +++ b/C4/Search.pm @@ -26,6 +26,7 @@ use C4::Search::PazPar2; use XML::Simple; use C4::Dates qw(format_date); use C4::XSLT; +use C4::Branch; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $DEBUG); @@ -53,44 +54,16 @@ This module provides searching functions for Koha's bibliographic databases @ISA = qw(Exporter); @EXPORT = qw( - &findseealso &FindDuplicate &SimpleSearch &searchResults &getRecords &buildQuery &NZgetRecords - &ModBiblios ); # make all your functions, whether exported or not; -=head2 findseealso($dbh,$fields); - -C<$dbh> is a link to the DB handler. - -use C4::Context; -my $dbh =C4::Context->dbh; - -C<$fields> is a reference to the fields array - -This function modifies the @$fields array and adds related fields to search on. - -FIXME: this function is probably deprecated in Koha 3 - -=cut - -sub findseealso { - my ( $dbh, $fields ) = @_; - my $tagslib = GetMarcStructure(1); - for ( my $i = 0 ; $i <= $#{$fields} ; $i++ ) { - my ($tag) = substr( @$fields[$i], 1, 3 ); - my ($subfield) = substr( @$fields[$i], 4, 1 ); - @$fields[$i] .= ',' . $tagslib->{$tag}->{$subfield}->{seealso} - if ( $tagslib->{$tag}->{$subfield}->{seealso} ); - } -} - =head2 FindDuplicate ($biblionumber,$biblionumber,$title) = FindDuplicate($record); @@ -224,7 +197,7 @@ sub SimpleSearch { my $search_result = ( $result->{hits} && $result->{hits} > 0 ? $result->{'RECORDS'} : [] ); - return ( undef, $search_result, scalar($search_result) ); + return ( undef, $search_result, scalar($result->{hits}) ); } else { # FIXME hardcoded value. See catalog/search.pl & opac-search.pl too. @@ -347,40 +320,21 @@ sub getRecords { # Check if we've got a query_type defined, if so, use it eval { - if ($query_type) - { - if ( $query_type =~ /^ccl/ ) { - $query_to_use =~ - s/\:/\=/g; # change : to = last minute (FIXME) - $results[$i] = - $zconns[$i]->search( - new ZOOM::Query::CCL2RPN( $query_to_use, $zconns[$i] ) - ); - } - elsif ( $query_type =~ /^cql/ ) { - $results[$i] = - $zconns[$i]->search( - new ZOOM::Query::CQL( $query_to_use, $zconns[$i] ) ); - } - elsif ( $query_type =~ /^pqf/ ) { - $results[$i] = - $zconns[$i]->search( - new ZOOM::Query::PQF( $query_to_use, $zconns[$i] ) ); - } - } - else { - if ($scan) { - $results[$i] = - $zconns[$i]->scan( - new ZOOM::Query::CCL2RPN( $query_to_use, $zconns[$i] ) - ); - } - else { - $results[$i] = - $zconns[$i]->search( - new ZOOM::Query::CCL2RPN( $query_to_use, $zconns[$i] ) - ); + if ($query_type) { + if ($query_type =~ /^ccl/) { + $query_to_use =~ s/\:/\=/g; # change : to = last minute (FIXME) + $results[$i] = $zconns[$i]->search(new ZOOM::Query::CCL2RPN($query_to_use, $zconns[$i])); + } elsif ($query_type =~ /^cql/) { + $results[$i] = $zconns[$i]->search(new ZOOM::Query::CQL($query_to_use, $zconns[$i])); + } elsif ($query_type =~ /^pqf/) { + $results[$i] = $zconns[$i]->search(new ZOOM::Query::PQF($query_to_use, $zconns[$i])); + } else { + warn "Unknown query_type '$query_type'. Results undetermined."; } + } elsif ($scan) { + $results[$i] = $zconns[$i]->scan( new ZOOM::Query::CCL2RPN($query_to_use, $zconns[$i])); + } else { + $results[$i] = $zconns[$i]->search(new ZOOM::Query::CCL2RPN($query_to_use, $zconns[$i])); } }; if ($@) { @@ -427,6 +381,9 @@ sub getRecords { elsif ( $sort eq "title_za" ) { $sort_by .= "1=4 >i "; } + else { + warn "Ignoring unrecognized sort '$sort' requested" if $sort_by; + } } if ($sort_by) { if ( $results[$i]->sort( "yaz", $sort_by ) < 0 ) { @@ -525,15 +482,15 @@ sub getRecords { if ( $servers[ $i - 1 ] =~ /biblioserver/ ) { for my $link_value ( sort { $facets_counter->{$b} <=> $facets_counter->{$a} } - keys %$facets_counter ) + keys %$facets_counter ) { my $expandable; my $number_of_facets; my @this_facets_array; for my $one_facet ( sort { - $facets_counter->{$link_value} - ->{$b} <=> $facets_counter->{$link_value}->{$a} + $facets_counter->{$link_value}->{$b} + <=> $facets_counter->{$link_value}->{$a} } keys %{ $facets_counter->{$link_value} } ) { @@ -559,21 +516,14 @@ sub getRecords { $branches->{$one_facet}->{'branchname'}; } - # but we're down with the whole label being in the link's title. - my $facet_title_value = $one_facet; - - push @this_facets_array, - ( - { - facet_count => - $facets_counter->{$link_value} - ->{$one_facet}, - facet_label_value => $facet_label_value, - facet_title_value => $facet_title_value, - facet_link_value => $facet_link_value, - type_link_value => $link_value, - }, - ); + # but we're down with the whole label being in the link's title. + push @this_facets_array, { + facet_count => $facets_counter->{$link_value}->{$one_facet}, + facet_label_value => $facet_label_value, + facet_title_value => $one_facet, + facet_link_value => $facet_link_value, + type_link_value => $link_value, + }; } } @@ -583,17 +533,14 @@ sub getRecords { if ( ( $number_of_facets > 6 ) && ( $expanded_facet ne $link_value ) ); } - push @facets_loop, - ( - { - type_link_value => $link_value, - type_id => $link_value . "_id", - "type_label_" . $facets_info->{$link_value}->{'label_value'} => 1, - facets => \@this_facets_array, - expandable => $expandable, - expand => $link_value, - } - ) unless ( ($facets_info->{$link_value}->{'label_value'} =~ /Libraries/) and (C4::Context->preference('singleBranchMode')) ); + push @facets_loop, { + type_link_value => $link_value, + type_id => $link_value . "_id", + "type_label_" . $facets_info->{$link_value}->{'label_value'} => 1, + facets => \@this_facets_array, + expandable => $expandable, + expand => $link_value, + } unless ( ($facets_info->{$link_value}->{'label_value'} =~ /Libraries/) and (C4::Context->preference('singleBranchMode')) ); } } } @@ -686,19 +633,16 @@ sub _remove_stopwords { # we use IsAlpha unicode definition, to deal correctly with diacritics. # otherwise, a French word like "leçon" woudl be split into "le" "çon", "le" # is a stopword, we'd get "çon" and wouldn't find anything... - foreach ( keys %{ C4::Context->stopwords } ) { - next if ( $_ =~ /(and|or|not)/ ); # don't remove operators - if ( $operand =~ - /(\P{IsAlpha}$_\P{IsAlpha}|^$_\P{IsAlpha}|\P{IsAlpha}$_$|^$_$)/ ) - { - $operand =~ s/\P{IsAlpha}$_\P{IsAlpha}/ /gi; - $operand =~ s/^$_\P{IsAlpha}/ /gi; - $operand =~ s/\P{IsAlpha}$_$/ /gi; - $operand =~ s/$1//gi; - push @stopwords_removed, $_; - } - } - } + foreach ( keys %{ C4::Context->stopwords } ) { + next if ( $_ =~ /(and|or|not)/ ); # don't remove operators + if ( my ($matched) = ($operand =~ + /(\P{IsAlnum}\Q$_\E\P{IsAlnum}|^\Q$_\E\P{IsAlnum}|\P{IsAlnum}\Q$_\E$|^\Q$_\E$)/gi) ) + { + $operand =~ s/\Q$matched\E/ /gi; + push @stopwords_removed, $_; + } + } + } return ( $operand, \@stopwords_removed ); } @@ -850,11 +794,11 @@ sub buildQuery { warn "---------\nEnter buildQuery\n---------" if $DEBUG; # dereference - my @operators = @$operators if $operators; - my @indexes = @$indexes if $indexes; - my @operands = @$operands if $operands; - my @limits = @$limits if $limits; - my @sort_by = @$sort_by if $sort_by; + my @operators = $operators ? @$operators : (); + my @indexes = $indexes ? @$indexes : (); + my @operands = $operands ? @$operands : (); + my @limits = $limits ? @$limits : (); + my @sort_by = $sort_by ? @$sort_by : (); my $stemming = C4::Context->preference("QueryStemming") || 0; my $auto_truncation = C4::Context->preference("QueryAutoTruncate") || 0; @@ -886,13 +830,13 @@ sub buildQuery { # for handling ccl, cql, pqf queries in diagnostic mode, skip the rest of the steps # DIAGNOSTIC ONLY!! if ( $query =~ /^ccl=/ ) { - return ( undef, $', $', $', $', '', '', '', '', 'ccl' ); + return ( undef, $', $', "q=ccl=$'", $', '', '', '', '', 'ccl' ); } if ( $query =~ /^cql=/ ) { - return ( undef, $', $', $', $', '', '', '', '', 'cql' ); + return ( undef, $', $', "q=cql=$'", $', '', '', '', '', 'cql' ); } if ( $query =~ /^pqf=/ ) { - return ( undef, $', $', $', $', '', '', '', '', 'pqf' ); + return ( undef, $', $', "q=pqf=$'", $', '', '', '', '', 'pqf' ); } # pass nested queries directly @@ -976,6 +920,14 @@ sub buildQuery { if ( $stopwords_removed && $DEBUG ); } + if ($auto_truncation){ + #FIXME only valid with LTR scripts + $operand=join(" ",map{ + "$_*" + }split (/\s+/,$operand)); + warn $operand if $DEBUG; + } + # Detect Truncation my $truncated_operand; my( $nontruncated, $righttruncated, $lefttruncated, @@ -995,29 +947,23 @@ sub buildQuery { $indexes_set = 1; undef $weight_fields; my $previous_truncation_operand; - if ( scalar(@$nontruncated) > 0 ) { + if (scalar @$nontruncated) { $truncated_operand .= "$index_plus @$nontruncated "; $previous_truncation_operand = 1; } - if ( scalar(@$righttruncated) > 0 ) { - $truncated_operand .= "and " - if $previous_truncation_operand; - $truncated_operand .= - "$index_plus_comma" . "rtrn:@$righttruncated "; + if (scalar @$righttruncated) { + $truncated_operand .= "and " if $previous_truncation_operand; + $truncated_operand .= $index_plus_comma . "rtrn:@$righttruncated "; $previous_truncation_operand = 1; } - if ( scalar(@$lefttruncated) > 0 ) { - $truncated_operand .= "and " - if $previous_truncation_operand; - $truncated_operand .= - "$index_plus_comma" . "ltrn:@$lefttruncated "; + if (scalar @$lefttruncated) { + $truncated_operand .= "and " if $previous_truncation_operand; + $truncated_operand .= $index_plus_comma . "ltrn:@$lefttruncated "; $previous_truncation_operand = 1; } - if ( scalar(@$rightlefttruncated) > 0 ) { - $truncated_operand .= "and " - if $previous_truncation_operand; - $truncated_operand .= - "$index_plus_comma" . "rltrn:@$rightlefttruncated "; + if (scalar @$rightlefttruncated) { + $truncated_operand .= "and " if $previous_truncation_operand; + $truncated_operand .= $index_plus_comma . "rltrn:@$rightlefttruncated "; $previous_truncation_operand = 1; } } @@ -1026,18 +972,19 @@ sub buildQuery { # Handle Stemming my $stemmed_operand; - $stemmed_operand = _build_stemmed_operand($operand) - if $stemming; + $stemmed_operand = _build_stemmed_operand($operand) if $stemming; + warn "STEMMED OPERAND: >$stemmed_operand<" if $DEBUG; # Handle Field Weighting my $weighted_operand; - $weighted_operand = - _build_weighted_query( $operand, $stemmed_operand, $index ) - if $weight_fields; + if ($weight_fields) { + $weighted_operand = _build_weighted_query( $operand, $stemmed_operand, $index ); + $operand = $weighted_operand; + $indexes_set = 1; + } + warn "FIELD WEIGHTED OPERAND: >$weighted_operand<" if $DEBUG; - $operand = $weighted_operand if $weight_fields; - $indexes_set = 1 if $weight_fields; # If there's a previous operand, we need to add an operator if ($previous_operand) { @@ -1108,12 +1055,20 @@ sub buildQuery { # Regular old limits else { - if ($this_limit){ - $limit .= " and " if $limit || $query; - $limit .= "$this_limit"; - $limit_cgi .= "&limit=$this_limit"; + $limit .= " and " if $limit || $query; + $limit .= "$this_limit"; + $limit_cgi .= "&limit=$this_limit"; + if ($this_limit =~ /^branch:(.+)/) { + my $branchcode = $1; + my $branchname = GetBranchName($branchcode); + if (defined $branchname) { + $limit_desc .= " branch:$branchname"; + } else { + $limit_desc .= " $this_limit"; + } + } else { $limit_desc .= " $this_limit"; - } + } } } if ($group_OR_limits) { @@ -1129,15 +1084,15 @@ sub buildQuery { $query =~ s/:/=/g; $limit =~ s/:/=/g; for ( $query, $query_desc, $limit, $limit_desc ) { - $_ =~ s/ / /g; # remove extra spaces - $_ =~ s/^ //g; # remove any beginning spaces - $_ =~ s/ $//g; # remove any ending spaces - $_ =~ s/==/=/g; # remove double == from query + s/ / /g; # remove extra spaces + s/^ //g; # remove any beginning spaces + s/ $//g; # remove any ending spaces + s/==/=/g; # remove double == from query } $query_cgi =~ s/^&//; # remove unnecessary & from beginning of the query cgi for ($query_cgi,$simple_query) { - $_ =~ s/"//g; + s/"//g; } # append the limit to the query $query .= " " . $limit; @@ -1250,11 +1205,11 @@ sub searchResults { # add imageurl to itemtype if there is one $oldbiblio->{imageurl} = getitemtypeimagelocation( 'opac', $itemtypes{ $oldbiblio->{itemtype} }->{imageurl} ); - $oldbiblio->{'authorised_value_images'} = C4::Items::get_authorised_value_images( C4::Biblio::get_biblio_authorised_values( $oldbiblio->{'biblionumber'} ) ); + $oldbiblio->{'authorised_value_images'} = C4::Items::get_authorised_value_images( C4::Biblio::get_biblio_authorised_values( $oldbiblio->{'biblionumber'}, $marcrecord ) ); (my $aisbn) = $oldbiblio->{isbn} =~ /([\d-]*[X]*)/; $aisbn =~ s/-//g; $oldbiblio->{amazonisbn} = $aisbn; - $oldbiblio->{description} = $itemtypes{ $oldbiblio->{itemtype} }->{description}; + $oldbiblio->{description} = $itemtypes{ $oldbiblio->{itemtype} }->{description}; # 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} ) { @@ -1292,6 +1247,7 @@ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g; # save an author with no tag, for the > link $oldbiblio->{'author_nospan'} = $oldbiblio->{'author'}; $oldbiblio->{'title_nospan'} = $oldbiblio->{'title'}; + $oldbiblio->{'subtitle_nospan'} = $oldbiblio->{'subtitle'}; # Add search-term highlighting to the whole record where they match using s if (C4::Context->preference("OpacHighlightedWords")){ my $searchhighlightblob; @@ -1336,15 +1292,18 @@ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g; # Setting item statuses for display my @available_items_loop; my @onloan_items_loop; + my @notforloan_items_loop; my @other_items_loop; my $available_items; my $onloan_items; + my $notforloan_items; my $other_items; my $ordered_count = 0; my $available_count = 0; my $onloan_count = 0; + my $notforloan_count = 0; my $longoverdue_count = 0; my $other_count = 0; my $wthdrawn_count = 0; @@ -1376,12 +1335,14 @@ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g; elsif ($item->{$otherbranch}) { # Last resort $item->{'branchname'} = $branches{$item->{$otherbranch}}; } - + + ($item->{'reserved'}) = C4::Reserves::CheckReserves($item->{itemnumber}); + 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} ) { + if ( $item->{onloan} or $item->{reserved} ) { $onloan_count++; - my $key = $prefix . $item->{due_date}; + my $key = $prefix . $item->{onloan} . $item->{barcode}; $onloan_items->{$key}->{due_date} = format_date($item->{onloan}); $onloan_items->{$key}->{count}++ if $item->{$hbranch}; $onloan_items->{$key}->{branchname} = $item->{branchname}; @@ -1436,6 +1397,7 @@ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g; || $item->{itemlost} || $item->{damaged} || $item->{notforloan} + || $item->{reserved} || ($transfertwhen ne '')) { $wthdrawn_count++ if $item->{wthdrawn}; @@ -1443,18 +1405,36 @@ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g; $itemdamaged_count++ if $item->{damaged}; $item_in_transit_count++ if $transfertwhen ne ''; $item->{status} = $item->{wthdrawn} . "-" . $item->{itemlost} . "-" . $item->{damaged} . "-" . $item->{notforloan}; - $other_count++; my $key = $prefix . $item->{status}; + foreach (qw(wthdrawn itemlost damaged branchname itemcallnumber)) { - $other_items->{$key}->{$_} = $item->{$_}; + if($item->{notforloan} == 1){ + $notforloan_items->{$key}->{$_} = $item->{$_}; + }else{ + $other_items->{$key}->{$_} = $item->{$_}; + } } - $other_items->{$key}->{intransit} = ($transfertwhen ne '') ? 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}->{barcode} = $item->{barcode}; + if($item->{notforloan} == 1){ + $notforloan_count++; + + $notforloan_items->{$key}->{intransit} = ($transfertwhen ne '') ? 1 : 0; + $notforloan_items->{$key}->{notforloan} = GetAuthorisedValueDesc('','',$item->{notforloan},'','',$notforloan_authorised_value) if $notforloan_authorised_value; + $notforloan_items->{$key}->{count}++ if $item->{$hbranch}; + $notforloan_items->{$key}->{location} = $shelflocations->{ $item->{location} }; + $notforloan_items->{$key}->{imageurl} = getitemtypeimagelocation( 'opac', $itemtypes{ $item->{itype} }->{imageurl} ); + $notforloan_items->{$key}->{barcode} = $item->{barcode}; + }else{ + $other_count++; + + $other_items->{$key}->{intransit} = ($transfertwhen ne '') ? 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}->{barcode} = $item->{barcode}; + } + } # item is available else { @@ -1469,7 +1449,7 @@ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g; } } } # notforloan, item level and biblioitem level - my ( $availableitemscount, $onloanitemscount, $otheritemscount ); + my ( $availableitemscount, $onloanitemscount, $notforloanitemscount,$otheritemscount ); $maxitems = ( C4::Context->preference('maxItemsinSearchResults') ) ? C4::Context->preference('maxItemsinSearchResults') - 1 @@ -1482,6 +1462,10 @@ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g; (++$otheritemscount > $maxitems) and last; push @other_items_loop, $other_items->{$key}; } + for my $key ( sort keys %$notforloan_items ) { + (++$notforloanitemscount > $maxitems) and last; + push @notforloan_items_loop, $notforloan_items->{$key}; + } for my $key ( sort keys %$available_items ) { (++$availableitemscount > $maxitems) and last; push @available_items_loop, $available_items->{$key} @@ -1489,23 +1473,24 @@ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g; # XSLT processing of some stuff if (C4::Context->preference("XSLTResultsDisplay") && !$scan) { - my $newxmlrecord = XSLTParse4Display($oldbiblio->{biblionumber},C4::Context->config('opachtdocs')."/prog/en/xslt/MARC21slim2OPACResults.xsl"); - $oldbiblio->{XSLTResultsRecord} = $newxmlrecord; + $oldbiblio->{XSLTResultsRecord} = XSLTParse4Display( + $oldbiblio->{biblionumber}, $marcrecord, 'Results' ); } # 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}; + $can_place_holds = 0 if $itemtypes{ $oldbiblio->{itemtype} }->{notforloan}; $oldbiblio->{norequests} = 1 unless $can_place_holds; $oldbiblio->{itemsplural} = 1 if $items_count > 1; $oldbiblio->{items_count} = $items_count; $oldbiblio->{available_items_loop} = \@available_items_loop; + $oldbiblio->{notforloan_items_loop}= \@notforloan_items_loop; $oldbiblio->{onloan_items_loop} = \@onloan_items_loop; $oldbiblio->{other_items_loop} = \@other_items_loop; $oldbiblio->{availablecount} = $available_count; $oldbiblio->{availableplural} = 1 if $available_count > 1; $oldbiblio->{onloancount} = $onloan_count; $oldbiblio->{onloanplural} = 1 if $onloan_count > 1; + $oldbiblio->{notforloancount} = $notforloan_count; $oldbiblio->{othercount} = $other_count; $oldbiblio->{otherplural} = 1 if $other_count > 1; $oldbiblio->{wthdrawncount} = $wthdrawn_count; @@ -1701,16 +1686,15 @@ sub NZanalyse { $left = 'subject' if $left =~ '^su$'; $left = 'koha-Auth-Number' if $left =~ '^an$'; $left = 'keyword' if $left =~ '^kw$'; + $left = 'itemtype' if $left =~ '^mc$'; # Fix for Bug 2599 - Search limits not working for NoZebra warn "handling leaf... left:$left operator:$operator right:$right" if $DEBUG; + my $dbh = C4::Context->dbh; if ( $operator && $left ne 'keyword' ) { - #do a specific search - my $dbh = C4::Context->dbh; $operator = 'LIKE' if $operator eq '=' and $right =~ /%/; - my $sth = - $dbh->prepare( + my $sth = $dbh->prepare( "SELECT biblionumbers,value FROM nozebra WHERE server=? AND indexname=? AND value $operator ?" - ); + ); warn "$left / $operator / $right\n" if $DEBUG; # split each word, query the DB and build the biblionumbers result @@ -1738,20 +1722,16 @@ sub NZanalyse { if ($results) { warn "NZAND" if $DEBUG; $results = NZoperatorAND($biblionumbers,$results); - } - else { + } else { $results = $biblionumbers; } } } else { - #do a complete search (all indexes), if index='kw' do complete search too. - my $dbh = C4::Context->dbh; - my $sth = - $dbh->prepare( + my $sth = $dbh->prepare( "SELECT biblionumbers FROM nozebra WHERE server=? AND value LIKE ?" - ); + ); # split each word, query the DB and build the biblionumbers result foreach ( split / /, $string ) { @@ -1864,7 +1844,7 @@ sub NZorder { my $popularity = $sth->fetchrow || 0; # hint : the key is popularity.title because we can have -# many results with the same popularity. In this cas, sub-ordering is done by title +# many results with the same popularity. In this case, sub-ordering is done by title # we also have biblionumber to avoid bug for 2 biblios with the same title & popularity # (un-frequent, I agree, but we won't forget anything that way ;-) $popularity{ sprintf( "%10d", $popularity ) . $title @@ -2125,130 +2105,6 @@ sub NZorder { } } -=head2 ModBiblios - -($countchanged,$listunchanged) = ModBiblios($listbiblios, $tagsubfield,$initvalue,$targetvalue,$test); - -this function changes all the values $initvalue in subfield $tag$subfield in any record in $listbiblios -test parameter if set donot perform change to records in database. - -=over 2 - -=item C - - * $listbiblios is an array ref to marcrecords to be changed - * $tagsubfield is the reference of the subfield to change. - * $initvalue is the value to search the record for - * $targetvalue is the value to set the subfield to - * $test is to be set only not to perform changes in database. - -=item C - * $countchanged counts all the changes performed. - * $listunchanged contains the list of all the biblionumbers of records unchanged. - -=item C - -=back - -my ($countchanged, $listunchanged) = EditBiblios($results->{RECORD}, $tagsubfield,$initvalue,$targetvalue);; -#If one wants to display unchanged records, you should get biblios foreach @$listunchanged -$template->param(countchanged => $countchanged, loopunchanged=>$listunchanged); - -=cut - -sub ModBiblios { - my ( $listbiblios, $tagsubfield, $initvalue, $targetvalue, $test ) = @_; - my $countmatched; - my @unmatched; - my ( $tag, $subfield ) = ( $1, $2 ) - if ( $tagsubfield =~ /^(\d{1,3})([a-z0-9A-Z@])?$/ ); - if ( ( length($tag) < 3 ) && $subfield =~ /0-9/ ) { - $tag = $tag . $subfield; - undef $subfield; - } - my ( $bntag, $bnsubf ) = GetMarcFromKohaField('biblio.biblionumber',''); - my ( $itemtag, $itemsubf ) = GetMarcFromKohaField('items.itemnumber',''); - if ($tag eq $itemtag) { - # do not allow the embedded item tag to be - # edited from here - warn "Attempting to edit item tag via C4::Search::ModBiblios -- not allowed"; - return (0, []); - } - foreach my $usmarc (@$listbiblios) { - my $record; - $record = eval { MARC::Record->new_from_usmarc($usmarc) }; - my $biblionumber; - if ($@) { - - # usmarc is not a valid usmarc May be a biblionumber - # FIXME - sorry, please let's figure out whether - # this function is to be passed a list of - # record numbers or a list of MARC::Record - # objects. The former is probably better - # because the MARC records supplied by Zebra - # may be not current. - $record = GetMarcBiblio($usmarc); - $biblionumber = $usmarc; - } - else { - if ( $bntag >= 010 ) { - $biblionumber = $record->subfield( $bntag, $bnsubf ); - } - else { - $biblionumber = $record->field($bntag)->data; - } - } - - #GetBiblionumber is to be written. - #Could be replaced by TransformMarcToKoha (But Would be longer) - if ( $record->field($tag) ) { - my $modify = 0; - foreach my $field ( $record->field($tag) ) { - if ($subfield) { - if ( - $field->delete_subfield( - 'code' => $subfield, - 'match' => qr($initvalue) - ) - ) - { - $countmatched++; - $modify = 1; - $field->update( $subfield, $targetvalue ) - if ($targetvalue); - } - } - else { - if ( $tag >= 010 ) { - if ( $field->delete_field($field) ) { - $countmatched++; - $modify = 1; - } - } - else { - $field->data = $targetvalue - if ( $field->data =~ qr($initvalue) ); - } - } - } - - # warn $record->as_formatted; - if ($modify) { - ModBiblio( $record, $biblionumber, - GetFrameworkCode($biblionumber) ) - unless ($test); - } - else { - push @unmatched, $biblionumber; - } - } - else { - push @unmatched, $biblionumber; - } - } - return ( $countmatched, \@unmatched ); -} - END { } # module clean-up code here (global destructor) 1;