# along with Koha; if not, see <http://www.gnu.org/licenses>.
use Modern::Perl;
-require Exporter;
use C4::Context;
-use C4::Biblio; # GetMarcFromKohaField, GetBiblioData
-use C4::Koha; # getFacets
+use C4::Biblio qw( TransformMarcToKoha GetMarcFromKohaField GetFrameworkCode GetAuthorisedValueDesc GetBiblioData );
+use C4::Koha qw( getFacets GetVariationsOfISBN GetNormalizedUPC GetNormalizedEAN GetNormalizedOCLCNumber GetNormalizedISBN getitemtypeimagelocation );
use Koha::DateUtils;
use Koha::Libraries;
use Lingua::Stem;
-use C4::Search::PazPar2;
use XML::Simple;
-use C4::XSLT;
-use C4::Reserves; # GetReserveStatus
-use C4::Debug;
-use C4::Charset;
+use C4::XSLT qw( XSLTParse4Display );
+use C4::Reserves qw( GetReserveStatus );
+use C4::Charset qw( SetUTF8Flag );
use Koha::AuthorisedValues;
use Koha::ItemTypes;
use Koha::Libraries;
+use Koha::Logger;
use Koha::Patrons;
use Koha::RecordProcessor;
-use YAML;
use URI::Escape;
use Business::ISBN;
use MARC::Record;
use MARC::Field;
-use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $DEBUG);
+our (@ISA, @EXPORT_OK);
BEGIN {
- $DEBUG = ($ENV{DEBUG}) ? 1 : 0;
+ require Exporter;
+ @ISA = qw(Exporter);
+ @EXPORT_OK = qw(
+ FindDuplicate
+ SimpleSearch
+ searchResults
+ getRecords
+ buildQuery
+ GetDistinctValues
+ enabled_staff_search_views
+ new_record_from_zebra
+ z3950_search_args
+ getIndexes
+ );
}
=head1 NAME
=cut
-@ISA = qw(Exporter);
-@EXPORT = qw(
- &FindDuplicate
- &SimpleSearch
- &searchResults
- &getRecords
- &buildQuery
- &GetDistinctValues
- &enabled_staff_search_views
-);
-
# make all your functions, whether exported or not;
=head2 FindDuplicate
$result->{title} =~ s /\(//g;
$result->{title} =~ s /\)//g;
- # FIXME: instead of removing operators, could just do
- # quotes around the value
- $result->{title} =~ s/(and|or|not)//g;
$query = "$titleindex:\"$result->{title}\"";
if ( $result->{author} ) {
$result->{author} =~ s /\\//g;
$result->{author} =~ s /\(//g;
$result->{author} =~ s /\)//g;
- # remove valid operators
- $result->{author} =~ s/(and|or|not)//g;
$query .= " $op $authorindex:\"$result->{author}\"";
}
}
- my ( $error, $searchresults, undef ) = SimpleSearch($query); # FIXME :: hardcoded !
+ my $searcher = Koha::SearchEngine::Search->new({index => $Koha::SearchEngine::BIBLIOS_INDEX});
+ my ( $error, $searchresults, undef ) = $searcher->simple_search_compat($query,0,50);
my @results;
if (!defined $error) {
foreach my $possible_duplicate_record (@{$searchresults}) {
eval {
$zconns[$i] = C4::Context->Zconn( $servers[$i], 1 );
$query =~ s/:/=/g unless $options{skip_normalize};
- $zoom_queries[$i] = new ZOOM::Query::CCL2RPN( $query, $zconns[$i]);
+ $zoom_queries[$i] = ZOOM::Query::CCL2RPN->new( $query, $zconns[$i]);
$tmpresults[$i] = $zconns[$i]->search( $zoom_queries[$i] );
# error handling
# if this is a local search, use the $koha-query, if it's a federated one, use the federated-query
my $query_to_use = ($servers[$i] =~ /biblioserver/) ? $koha_query : $simple_query;
- #$query_to_use = $simple_query if $scan;
- warn $simple_query if ( $scan and $DEBUG );
+ Koha::Logger->get->debug($simple_query) if $scan;
# 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]));
+ $results[$i] = $zconns[$i]->search(ZOOM::Query::CCL2RPN->new($query_to_use, $zconns[$i]));
} elsif ($query_type =~ /^cql/) {
- $results[$i] = $zconns[$i]->search(new ZOOM::Query::CQL($query_to_use, $zconns[$i]));
+ $results[$i] = $zconns[$i]->search(ZOOM::Query::CQL->new($query_to_use, $zconns[$i]));
} elsif ($query_type =~ /^pqf/) {
- $results[$i] = $zconns[$i]->search(new ZOOM::Query::PQF($query_to_use, $zconns[$i]));
+ $results[$i] = $zconns[$i]->search(ZOOM::Query::PQF->new($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]));
+ $results[$i] = $zconns[$i]->scan( ZOOM::Query::CCL2RPN->new($query_to_use, $zconns[$i]));
} else {
- $results[$i] = $zconns[$i]->search(new ZOOM::Query::CCL2RPN($query_to_use, $zconns[$i]));
+ $results[$i] = $zconns[$i]->search(ZOOM::Query::CCL2RPN->new($query_to_use, $zconns[$i]));
}
};
if ($@) {
return $facets_info;
}
-sub pazGetRecords {
- my (
- $koha_query, $simple_query, $sort_by_ref, $servers_ref,
- $results_per_page, $offset, $branches, $query_type,
- $scan
- ) = @_;
- #NOTE: Parameter $branches is not used here !
-
- my $paz = C4::Search::PazPar2->new(C4::Context->config('pazpar2url'));
- $paz->init();
- $paz->search($simple_query);
- sleep 1; # FIXME: WHY?
-
- # do results
- my $results_hashref = {};
- my $stats = XMLin($paz->stat);
- my $results = XMLin($paz->show($offset, $results_per_page, 'work-title:1'), forcearray => 1);
-
- # for a grouped search result, the number of hits
- # is the number of groups returned; 'bib_hits' will have
- # the total number of bibs.
- $results_hashref->{'biblioserver'}->{'hits'} = $results->{'merged'}->[0];
- $results_hashref->{'biblioserver'}->{'bib_hits'} = $stats->{'hits'};
-
- HIT: foreach my $hit (@{ $results->{'hit'} }) {
- my $recid = $hit->{recid}->[0];
-
- my $work_title = $hit->{'md-work-title'}->[0];
- my $work_author;
- if (exists $hit->{'md-work-author'}) {
- $work_author = $hit->{'md-work-author'}->[0];
- }
- my $group_label = (defined $work_author) ? "$work_title / $work_author" : $work_title;
-
- my $result_group = {};
- $result_group->{'group_label'} = $group_label;
- $result_group->{'group_merge_key'} = $recid;
-
- my $count = 1;
- if (exists $hit->{count}) {
- $count = $hit->{count}->[0];
- }
- $result_group->{'group_count'} = $count;
-
- for (my $i = 0; $i < $count; $i++) {
- # FIXME -- may need to worry about diacritics here
- my $rec = $paz->record($recid, $i);
- push @{ $result_group->{'RECORDS'} }, $rec;
- }
-
- push @{ $results_hashref->{'biblioserver'}->{'GROUPS'} }, $result_group;
- }
-
- # pass through facets
- my $termlist_xml = $paz->termlist('author,subject');
- my $terms = XMLin($termlist_xml, forcearray => 1);
- my @facets_loop = ();
- #die Dumper($results);
-# foreach my $list (sort keys %{ $terms->{'list'} }) {
-# my @facets = ();
-# foreach my $facet (sort @{ $terms->{'list'}->{$list}->{'term'} } ) {
-# push @facets, {
-# facet_label_value => $facet->{'name'}->[0],
-# };
-# }
-# push @facets_loop, ( {
-# type_label => $list,
-# facets => \@facets,
-# } );
-# }
-
- return ( undef, $results_hashref, \@facets_loop );
-}
-
# TRUNCATION
sub _detect_truncation {
my ( $operand, $index ) = @_;
unless ( $stem =~ /(and$|or$|not$)/ ) || ( length($stem) < 3 );
$stemmed_operand .= " ";
}
- warn "STEMMED OPERAND: $stemmed_operand" if $DEBUG;
+
+ Koha::Logger->get->debug("STEMMED OPERAND: $stemmed_operand");
return $stemmed_operand;
}
sub buildQuery {
my ( $operators, $operands, $indexes, $limits, $sort_by, $scan, $lang) = @_;
- warn "---------\nEnter buildQuery\n---------" if $DEBUG;
my $query_desc;
my $weight_fields = C4::Context->preference("QueryWeightFields") || 0;
my $fuzzy_enabled = C4::Context->preference("QueryFuzzy") || 0;
- my $query = $operands[0];
+ my $query = $operands[0] // "";
my $simple_query = $operands[0];
# initialize the variables we're passing back
$operand=join(" ",map{
(index($_,"*")>0?"$_":"$_*")
}split (/\s+/,$operand));
- warn $operand if $DEBUG;
}
}
# Detect Truncation
- my $truncated_operand;
+ my $truncated_operand = q{};
my( $nontruncated, $righttruncated, $lefttruncated,
$rightlefttruncated, $regexpr
) = _detect_truncation( $operand, $index );
- warn
-"TRUNCATION: NON:>@$nontruncated< RIGHT:>@$righttruncated< LEFT:>@$lefttruncated< RIGHTLEFT:>@$rightlefttruncated< REGEX:>@$regexpr<"
- if $DEBUG;
+
+ Koha::Logger->get->debug(
+ "TRUNCATION: NON:>@$nontruncated< RIGHT:>@$righttruncated< LEFT:>@$lefttruncated< RIGHTLEFT:>@$rightlefttruncated< REGEX:>@$regexpr<");
# Apply Truncation
if (
}
}
$operand = $truncated_operand if $truncated_operand;
- warn "TRUNCATED OPERAND: >$truncated_operand<" if $DEBUG;
+ Koha::Logger->get->debug("TRUNCATED OPERAND: >$truncated_operand<");
# Handle Stemming
- my $stemmed_operand;
+ my $stemmed_operand = q{};
$stemmed_operand = _build_stemmed_operand($operand, $lang)
if $stemming;
- warn "STEMMED OPERAND: >$stemmed_operand<" if $DEBUG;
+ Koha::Logger->get->debug("STEMMED OPERAND: >$stemmed_operand<");
# Handle Field Weighting
- my $weighted_operand;
+ my $weighted_operand = q{};
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;
+ Koha::Logger->get->debug("FIELD WEIGHTED OPERAND: >$weighted_operand<");
+
+ #Use relevance ranking when not using a weighted query (which adds relevance ranking of its own)
+
+ #N.B. Truncation is mutually exclusive with Weighted Queries,
+ #so even if QueryWeightFields is turned on, QueryAutoTruncate will turn it off, thus
+ #the need for this relevance wrapper.
+ $operand = "(rk=($operand))" unless $weight_fields;
($query,$query_cgi,$query_desc,$previous_operand) = _build_initial_query({
query => $query,
} #/if $operands
} # /for
}
- warn "QUERY BEFORE LIMITS: >$query<" if $DEBUG;
+ Koha::Logger->get->debug("QUERY BEFORE LIMITS: >$query<");
# add limits
my %group_OR_limits;
$query =~ s/(?<=(st-date-normalized)):/=/g;
# Removing warnings for later substitutions
- $query //= q{};
- $query_desc //= q{};
- $query_cgi //= q{};
- $limit //= q{};
- $limit_desc //= q{};
+ $query //= q{};
+ $query_desc //= q{};
+ $query_cgi //= q{};
+ $limit //= q{};
+ $limit_desc //= q{};
+ $limit_cgi //= q{};
+ $simple_query //= q{};
$limit =~ s/:/=/g;
for ( $query, $query_desc, $limit, $limit_desc ) {
s/ +/ /g; # remove extra spaces
# append the limit to the query
$query .= " " . $limit;
- # Warnings if DEBUG
- if ($DEBUG) {
- warn "QUERY:" . $query;
- warn "QUERY CGI:" . $query_cgi;
- warn "QUERY DESC:" . $query_desc;
- warn "LIMIT:" . $limit;
- warn "LIMIT CGI:" . $limit_cgi;
- warn "LIMIT DESC:" . $limit_desc;
- warn "---------\nLeave buildQuery\n---------";
- }
+ Koha::Logger->get->debug(
+ sprintf "buildQuery returns\nQUERY:%s\nQUERY CGI:%s\nQUERY DESC:%s\nLIMIT:%s\nLIMIT CGI:%s\nLIMIT DESC:%s",
+ $query, $query_cgi, $query_desc, $limit, $limit_cgi, $limit_desc );
return (
undef, $query, $simple_query, $query_cgi,
}
# handle which records to actually retrieve
- my $times;
+ my $times; # Times is which record to process up to
if ( $hits && $offset + $results_per_page <= $hits ) {
$times = $offset + $results_per_page;
}
else {
- $times = $hits; # FIXME: if $hits is undefined, why do we want to equal it?
+ $times = $hits; # If less hits than results_per_page+offset we go to the end
}
my $marcflavour = C4::Context->preference("marcflavour");
: GetFrameworkCode($marcrecord->subfield($bibliotag,$bibliosubf));
SetUTF8Flag($marcrecord);
- my $oldbiblio = TransformMarcToKoha( $marcrecord, $fw );
+ my $oldbiblio = TransformMarcToKoha( $marcrecord, $fw, 'no_items' );
$oldbiblio->{result_number} = $i + 1;
$oldbiblio->{normalized_upc} = GetNormalizedUPC( $marcrecord,$marcflavour);
$oldbiblio->{normalized_ean} = GetNormalizedEAN( $marcrecord,$marcflavour);
$oldbiblio->{normalized_oclc} = GetNormalizedOCLCNumber($marcrecord,$marcflavour);
- $oldbiblio->{normalized_isbn} = GetNormalizedISBN(undef,$marcrecord,$marcflavour);
+ $oldbiblio->{normalized_isbn} = GetNormalizedISBN($oldbiblio->{isbn},$marcrecord,$marcflavour); # Use existing ISBN from record if we got one
$oldbiblio->{content_identifier_exists} = 1 if ($oldbiblio->{normalized_isbn} or $oldbiblio->{normalized_oclc} or $oldbiblio->{normalized_ean} or $oldbiblio->{normalized_upc});
# edition information, if any
$onloan_items->{$key}->{due_date} = $item->{onloan};
$onloan_items->{$key}->{count}++ if $item->{$hbranch};
$onloan_items->{$key}->{branchname} = $item->{branchname};
- $onloan_items->{$key}->{location} = $shelflocations->{ $item->{location} };
+ $onloan_items->{$key}->{location} = $shelflocations->{ $item->{location} } if $item->{location};
$onloan_items->{$key}->{itemcallnumber} = $item->{itemcallnumber};
$onloan_items->{$key}->{description} = $item->{description};
$onloan_items->{$key}->{imageurl} =
} # notforloan, item level and biblioitem level
# if all items are hidden, do not show the record
- if ($items_count > 0 && $hideatopac_count == $items_count) {
+ if ( C4::Context->preference('OpacHiddenItemsHidesRecord') && $items_count > 0 && $hideatopac_count == $items_count) {
next;
}
if ($fieldname=~/\./){
my ($table,$column)=split /\./, $fieldname;
my $dbh = C4::Context->dbh;
- warn "select DISTINCT($column) as value, count(*) as cnt from $table group by lib order by $column " if $DEBUG;
my $sth = $dbh->prepare("select DISTINCT($column) as value, count(*) as cnt from $table ".($string?" where $column like \"$string%\"":"")."group by value order by $column ");
$sth->execute;
my $elements=$sth->fetchall_arrayref({});