use Business::ISBN;
use MARC::Record;
use MARC::Field;
-
+use utf8;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $DEBUG);
# set the version for version checking
&AddSearchHistory
&GetDistinctValues
&enabled_staff_search_views
- &SimpleSearch
+ &PurgeSearchHistory
);
# make all your functions, whether exported or not;
$titleindex = 'title|exact';
$authorindex = 'author|exact';
$op = '&&';
+ $QParser->custom_data->{'QueryAutoTruncate'} = C4::Context->preference('QueryAutoTruncate');
} else {
$titleindex = 'ti,ext';
$authorindex = 'au,ext';
my $QParser;
$QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser') && ! ($query =~ m/\w,\w|\w=\w/));
+ if ($QParser) {
+ $QParser->custom_data->{'QueryAutoTruncate'} = C4::Context->preference('QueryAutoTruncate');
+ }
# Initialize & Search Zebra
for ( my $i = 0 ; $i < @servers ; $i++ ) {
# not an index scan
else {
$record = $results[ $i - 1 ]->record($j)->raw();
- utf8::decode( $record );
# warn "RECORD $j:".$record;
$results_hash->{'RECORDS'}[$j] = $record;
for ( my $j = 0 ; $j < $jmax ; $j++ ) {
my $render_record =
$results[ $i - 1 ]->record($j)->render();
- utf8::decode($render_record);
my @used_datas = ();
foreach my $tag ( @{ $facet->{tags} } ) {
for (my $i = 0; $i < $count; $i++) {
# FIXME -- may need to worry about diacritics here
my $rec = $paz->record($recid, $i);
- utf8::decode( $rec );
push @{ $result_group->{'RECORDS'} }, $rec;
}
my @stopwords_removed;
# phrase and exact-qualified indexes shouldn't have stopwords removed
- if ( $index !~ m/phr|ext/ ) {
+ if ( $index !~ m/,(phr|ext)/ ) {
# remove stopwords from operand : parse all stopwords & remove them (case insensitive)
# we use IsAlpha unicode definition, to deal correctly with diacritics.
my $stemming = C4::Context->preference("QueryStemming") || 0;
my $weight_fields = C4::Context->preference("QueryWeightFields") || 0;
my $fuzzy_enabled = C4::Context->preference("QueryFuzzy") || 0;
+ $operand =~ s/"/ /g; # Bug 7518: searches with quotation marks don't work
my $weighted_query .= "(rk=("; # Specifies that we're applying rank
'Corporate-name-heading',
'Corporate-name-see',
'Corporate-name-seealso',
+ 'Country-publication',
'ctype',
'date-entered-on-file',
'Date-of-acquisition',
'Koha-Auth-Number',
'l-format',
'language',
+ 'language-original',
'lc-card',
'LC-card-number',
'lcn',
if ($QParser)
{
+ $QParser->custom_data->{'QueryAutoTruncate'} = C4::Context->preference('QueryAutoTruncate');
$query = '';
for ( my $ii = 0 ; $ii <= @operands ; $ii++ ) {
next unless $operands[$ii];
$query .= $operators[ $ii - 1 ] eq 'or' ? ' || ' : ' && '
if ($query);
- if ( $indexes[$ii] =~ m/su-/ ) {
+ if ( $operands[$ii] =~ /^[^"]\W*[-|_\w]*:\w.*[^"]$/ ) {
+ $query .= $operands[$ii];
+ }
+ elsif ( $indexes[$ii] =~ m/su-/ ) {
$query .= $indexes[$ii] . '(' . $operands[$ii] . ')';
}
else {
my $cclq = 0;
my $cclindexes = getIndexes();
- if ( $query !~ /\s*ccl=/ ) {
+ if ( $query !~ /\s*(ccl=|pqf=|cql=)/ ) {
while ( !$cclq && $query =~ /(?:^|\W)([\w-]+)(,[\w-]+)*[:=]/g ) {
my $dx = lc($1);
$cclq = grep { lc($_) eq $dx } @$cclindexes;
if ( @limits ) {
$q .= ' and '.join(' and ', @limits);
}
- return ( undef, $q, $q, "q=ccl=".uri_escape_utf8($q), $q, '', '', '', '', 'ccl' );
+ return ( undef, $q, $q, "q=ccl=".uri_escape($q), $q, '', '', '', '', 'ccl' );
}
if ( $query =~ /^cql=/ ) {
- return ( undef, $', $', "q=cql=".uri_escape_utf8($'), $', '', '', '', '', 'cql' );
+ return ( undef, $', $', "q=cql=".uri_escape($'), $', '', '', '', '', 'cql' );
}
if ( $query =~ /^pqf=/ ) {
if ($query_desc) {
- $query_cgi = "q=".uri_escape_utf8($query_desc);
+ $query_cgi = "q=".uri_escape($query_desc);
} else {
$query_desc = $';
- $query_cgi = "q=pqf=".uri_escape_utf8($');
+ $query_cgi = "q=pqf=".uri_escape($');
}
return ( undef, $', $', $query_cgi, $query_desc, '', '', '', '', 'pqf' );
}
# Set default structure attribute (word list)
my $struct_attr = q{};
- unless ( $indexes_set || !$index || $index =~ /(st-|phr|ext|wrdl|nb|ns)/ ) {
+ unless ( $indexes_set || !$index || $index =~ /,(st-|phr|ext|wrdl)/ || $index =~ /^(nb|ns)$/ ) {
$struct_attr = ",wrdl";
}
}
if ($auto_truncation){
- unless ( $index =~ /(st-|phr|ext)/ ) {
+ unless ( $index =~ /,(st-|phr|ext)/ ) {
#FIXME only valid with LTR scripts
$operand=join(" ",map{
(index($_,"*")>0?"$_":"$_*")
$query .= " $operators[$i-1] ";
$query .= " $index_plus " unless $indexes_set;
$query .= " $operand";
- $query_cgi .= "&op=".uri_escape_utf8($operators[$i-1]);
- $query_cgi .= "&idx=".uri_escape_utf8($index) if $index;
- $query_cgi .= "&q=".uri_escape_utf8($operands[$i]) if $operands[$i];
+ $query_cgi .= "&op=".uri_escape($operators[$i-1]);
+ $query_cgi .= "&idx=".uri_escape($index) if $index;
+ $query_cgi .= "&q=".uri_escape($operands[$i]) if $operands[$i];
$query_desc .=
" $operators[$i-1] $index_plus $operands[$i]";
}
$query .= " and ";
$query .= "$index_plus " unless $indexes_set;
$query .= "$operand";
- $query_cgi .= "&op=and&idx=".uri_escape_utf8($index) if $index;
- $query_cgi .= "&q=".uri_escape_utf8($operands[$i]) if $operands[$i];
+ $query_cgi .= "&op=and&idx=".uri_escape($index) if $index;
+ $query_cgi .= "&q=".uri_escape($operands[$i]) if $operands[$i];
$query_desc .= " and $index_plus $operands[$i]";
}
}
$query .= " $index_plus " unless $indexes_set;
$query .= $operand;
$query_desc .= " $index_plus $operands[$i]";
- $query_cgi .= "&idx=".uri_escape_utf8($index) if $index;
- $query_cgi .= "&q=".uri_escape_utf8($operands[$i]) if $operands[$i];
+ $query_cgi .= "&idx=".uri_escape($index) if $index;
+ $query_cgi .= "&q=".uri_escape($operands[$i]) if $operands[$i];
$previous_operand = 1;
}
} #/if $operands
while ( ( my $column ) = $sth2->fetchrow ) {
my ( $tagfield, $tagsubfield ) =
&GetMarcFromKohaField( "items." . $column, "" );
- $subfieldstosearch{$column} = $tagsubfield;
+ if ( defined $tagsubfield ) {
+ $subfieldstosearch{$column} = $tagsubfield;
+ }
}
# handle which records to actually retrieve
# 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] );
+ my $marcrecord = eval { MARC::File::USMARC::decode( $marcresults->[$i] ); };
+ if ( $@ ) {
+ warn "ERROR DECODING RECORD - $@: " . $marcresults->[$i];
+ next;
+ }
+
my $fw = $scan
? undef
: $bibliotag < 10
my $onloan_count = 0;
my $longoverdue_count = 0;
my $other_count = 0;
- my $wthdrawn_count = 0;
+ my $withdrawn_count = 0;
my $itemlost_count = 0;
my $hideatopac_count = 0;
my $itembinding_count = 0;
# is item on the reserve shelf?
my $reservestatus = '';
- unless ($item->{wthdrawn}
+ unless ($item->{withdrawn}
|| $item->{itemlost}
|| $item->{damaged}
|| $item->{notforloan}
}
# item is withdrawn, lost, damaged, not for loan, reserved or in transit
- if ( $item->{wthdrawn}
+ if ( $item->{withdrawn}
|| $item->{itemlost}
|| $item->{damaged}
|| $item->{notforloan}
|| $reservestatus eq 'Waiting'
|| ($transfertwhen ne ''))
{
- $wthdrawn_count++ if $item->{wthdrawn};
+ $withdrawn_count++ if $item->{withdrawn};
$itemlost_count++ if $item->{itemlost};
$itemdamaged_count++ if $item->{damaged};
$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->{itemlost} ) {
- if ( !$item->{wthdrawn} ){
- if ( $item->{damaged} ){
- if ( C4::Context->preference('AllowHoldsOnDamagedItems') ){
- # can place a hold on a damaged item if AllowHoldsOnDamagedItems is true
- if ( ( !$item->{notforloan} || $item->{notforloan} < 0 ) ){
- # item is either for loan or has notforloan < 0
- $can_place_holds = 1;
- }
- }
- } elsif ( $item->{notforloan} < 0 ) {
- # item is not damaged and notforloan is < 0
- $can_place_holds = 1;
- }
- }
- }
+ $item->{status} = $item->{withdrawn} . "-" . $item->{itemlost} . "-" . $item->{damaged} . "-" . $item->{notforloan};
+
+ # can place a hold on a item if
+ # not lost nor withdrawn
+ # not damaged unless AllowHoldsOnDamagedItems is true
+ # item is either for loan or on order (notforloan < 0)
+ $can_place_holds = 1
+ if (
+ !$item->{itemlost}
+ && !$item->{withdrawn}
+ && ( !$item->{damaged} || C4::Context->preference('AllowHoldsOnDamagedItems') )
+ && ( !$item->{notforloan} || $item->{notforloan} < 0 )
+ );
$other_count++;
my $key = $prefix . $item->{status};
- foreach (qw(wthdrawn itemlost damaged branchname itemcallnumber)) {
+ foreach (qw(withdrawn itemlost damaged branchname itemcallnumber)) {
$other_items->{$key}->{$_} = $item->{$_};
}
$other_items->{$key}->{intransit} = ( $transfertwhen ne '' ) ? 1 : 0;
$oldbiblio->{onloanplural} = 1 if $onloan_count > 1;
$oldbiblio->{othercount} = $other_count;
$oldbiblio->{otherplural} = 1 if $other_count > 1;
- $oldbiblio->{wthdrawncount} = $wthdrawn_count;
+ $oldbiblio->{withdrawncount} = $withdrawn_count;
$oldbiblio->{itemlostcount} = $itemlost_count;
$oldbiblio->{damagedcount} = $itemdamaged_count;
$oldbiblio->{intransitcount} = $item_in_transit_count;
return $sth->fetchall_hashref({});
}
+sub PurgeSearchHistory{
+ my ($pSearchhistory)=@_;
+ my $dbh = C4::Context->dbh;
+ my $sth = $dbh->prepare("DELETE FROM search_history WHERE time < DATE_SUB( NOW(), INTERVAL ? DAY )");
+ $sth->execute($pSearchhistory) or die $dbh->errstr;
+}
+
=head2 z3950_search_args
$arrayref = z3950_search_args($matchpoints)
sub z3950_search_args {
my $bibrec = shift;
- my $isbn = Business::ISBN->new($bibrec);
+
+ my $isbn_string = ref( $bibrec ) ? $bibrec->{title} : $bibrec;
+ my $isbn = Business::ISBN->new( $isbn_string );
if (defined $isbn && $isbn->is_valid)
{
- $bibrec = { isbn => $bibrec } if !ref $bibrec;
+ if ( ref($bibrec) ) {
+ $bibrec->{isbn} = $isbn_string;
+ $bibrec->{title} = undef;
+ } else {
+ $bibrec = { isbn => $isbn_string };
+ }
}
else {
$bibrec = { title => $bibrec } if !ref $bibrec;