use C4::Koha qw( getFacets GetVariationsOfISBN GetNormalizedUPC GetNormalizedEAN GetNormalizedOCLCNumber GetNormalizedISBN getitemtypeimagelocation );
use Koha::DateUtils;
use Koha::Libraries;
+use Koha::SearchEngine::QueryBuilder;
use Lingua::Stem;
use XML::Simple;
use C4::XSLT qw( XSLTParse4Display );
use Koha::Patrons;
use Koha::Recalls;
use Koha::RecordProcessor;
+use Koha::SearchFilters;
use URI::Escape;
use Business::ISBN;
use MARC::Record;
sub FindDuplicate {
my ($record) = @_;
my $dbh = C4::Context->dbh;
- my $result = TransformMarcToKoha( $record, '' );
+ my $result = TransformMarcToKoha({ record => $record });
my $sth;
my $query;
$possible_duplicate_record
);
- my $result = TransformMarcToKoha( $marcrecord, '' );
+ my $result = TransformMarcToKoha({ record => $marcrecord });
# FIXME :: why 2 $biblionumber ?
if ($result) {
for my $r ( @{$marcresults} ) {
my $marcrecord = MARC::File::USMARC::decode($r);
- my $biblio = TransformMarcToKoha($marcrecord,q{});
+ my $biblio = TransformMarcToKoha({ record => $marcrecord });
#build the iarray of hashs for the template.
push @results, {
elsif ( $sort eq "title_za" || $sort eq "title_dsc" ) {
$sort_by .= "1=4 >i ";
}
+ elsif ( $sort eq "biblionumber_az" || $sort eq "biblionumber_asc" ) {
+ $sort_by .= "1=12 <i ";
+ }
+ elsif ( $sort eq "biblionumber_za" || $sort eq "biblionumber_dsc" ) {
+ $sort_by .= "1=12 >i ";
+ }
else {
warn "Ignoring unrecognized sort '$sort' requested" if $sort_by;
}
my $query_cgi;
my $query_type;
- my $limit;
+ my $limit = q{};
my $limit_cgi;
my $limit_desc;
$query = "ccl=$query" if $cclq;
}
+ # add limits
+ my %group_OR_limits;
+ my $availability_limit;
+ foreach my $this_limit (@limits) {
+ next unless $this_limit;
+ if ( $this_limit =~ /available/ ) {
+#
+## 'available' is defined as (items.onloan is NULL) and (items.itemlost = 0)
+## In English:
+## all records not indexed in the onloan register (zebra) and all records with a value of lost equal to 0
+ $availability_limit .=
+"( (allrecords,AlwaysMatches='') and (not-onloan-count,st-numeric >= 1) and (lost,st-numeric=0) )";
+ $limit_cgi .= "&limit=available";
+ $limit_desc .= "";
+ }
+
+ # group_OR_limits, prefixed by mc-
+ # OR every member of the group
+ elsif ( $this_limit =~ /mc/ ) {
+ my ($k,$v) = split(/:/, $this_limit,2);
+ if ( $k !~ /mc-i(tem)?type/ ) {
+ # in case the mc-ccode value has complicating chars like ()'s inside it we wrap in quotes
+ $this_limit =~ tr/"//d;
+ $this_limit = $k.':"'.$v.'"';
+ }
+
+ $group_OR_limits{$k} .= " or " if $group_OR_limits{$k};
+ $limit_desc .= " or " if $group_OR_limits{$k};
+ $group_OR_limits{$k} .= "$this_limit";
+ $limit_cgi .= "&limit=" . uri_escape_utf8($this_limit);
+ $limit_desc .= " $this_limit";
+ }
+ elsif ( $this_limit =~ '^multibranchlimit:|^branch:' ) {
+ $limit_cgi .= "&limit=" . uri_escape_utf8($this_limit);
+ $limit .= " and " if $limit || $query;
+ my $branchfield = C4::Context->preference('SearchLimitLibrary');
+ my @branchcodes;
+ if( $this_limit =~ '^multibranchlimit:' ){
+ my ($group_id) = ( $this_limit =~ /^multibranchlimit:(.*)$/ );
+ my $search_group = Koha::Library::Groups->find( $group_id );
+ @branchcodes = map { $_->branchcode } $search_group->all_libraries;
+ @branchcodes = sort { $a cmp $b } @branchcodes;
+ } else {
+ @branchcodes = ( $this_limit =~ /^branch:(.*)$/ );
+ }
+
+ if (@branchcodes) {
+ if ( $branchfield eq "homebranch" ) {
+ $this_limit = sprintf "(%s)", join " or ", map { 'homebranch: ' . $_ } @branchcodes;
+ }
+ elsif ( $branchfield eq "holdingbranch" ) {
+ $this_limit = sprintf "(%s)", join " or ", map { 'holdingbranch: ' . $_ } @branchcodes;
+ }
+ else {
+ $this_limit = sprintf "(%s or %s)",
+ join( " or ", map { 'homebranch: ' . $_ } @branchcodes ),
+ join( " or ", map { 'holdingbranch: ' . $_ } @branchcodes );
+ }
+ }
+ $limit .= "$this_limit";
+ $limit_desc .= " $this_limit";
+ } elsif ( $this_limit =~ '^search_filter:' ) {
+ # Here we will get the query as a string, append to the limits, and pass through buildQuery
+ # again to clean the terms and handle nested filters
+ $limit_cgi .= "&limit=" . uri_escape_utf8($this_limit);
+ my ($filter_id) = ( $this_limit =~ /^search_filter:(.*)$/ );
+ my $search_filter = Koha::SearchFilters->find( $filter_id );
+ next unless $search_filter;
+ my ($expanded_lim, $query_lim) = $search_filter->expand_filter;
+ push @$expanded_lim, $query_lim;
+ my ( $error, undef, undef, undef, undef, $fixed_limit, undef, undef, undef ) = buildQuery ( undef, undef, undef, $expanded_lim, undef, undef, $lang);
+ $limit .= " and " if $limit || $query;
+ $limit .= "$fixed_limit";
+ $limit_desc .= " $limit";
+ }
+
+ # Regular old limits
+ else {
+ $limit .= " and " if $limit || $query;
+ $limit .= "$this_limit";
+ $limit_cgi .= "&limit=" . uri_escape_utf8($this_limit);
+ $limit_desc .= " $this_limit";
+ }
+ }
+ foreach my $k (keys (%group_OR_limits)) {
+ $limit .= " and " if ( $query || $limit );
+ $limit .= "($group_OR_limits{$k})";
+ }
+ if ($availability_limit) {
+ $limit .= " and " if ( $query || $limit );
+ $limit .= "($availability_limit)";
+ }
+
# for handling ccl, cql, pqf queries in diagnostic mode, skip the rest of the steps
# DIAGNOSTIC ONLY!!
if ( $query =~ /^ccl=/ ) {
my $q=$';
# This is needed otherwise ccl= and &limit won't work together, and
# this happens when selecting a subject on the opac-detail page
- @limits = grep {!/^$/} @limits;
my $original_q = $q; # without available part
- unless ( grep { $_ eq 'available' } @limits ) {
- $q =~ s| and \( \(allrecords,AlwaysMatches=''\) and \(not-onloan-count,st-numeric >= 1\) and \(lost,st-numeric=0\) \)||;
- $original_q = $q;
- }
- if ( @limits ) {
- if ( grep { $_ eq 'available' } @limits ) {
- $q .= q| and ( (allrecords,AlwaysMatches='') and (not-onloan-count,st-numeric >= 1) and (lost,st-numeric=0) )|;
- @limits = grep {!/^available$/} @limits;
- }
- $q .= ' and '.join(' and ', @limits) if @limits;
- }
+ $q .= $limit if $limit;
return ( undef, $q, $q, "q=ccl=".uri_escape_utf8($q), $original_q, '', '', '', 'ccl' );
}
if ( $query =~ /^cql=/ ) {
if ( $index eq 'nb' ) {
if ( C4::Context->preference("SearchWithISBNVariations") ) {
my @isbns = C4::Koha::GetVariationsOfISBN( $operand );
- $operands[$i] = $operand = '(nb=' . join(' OR nb=', @isbns) . ')';
+ $operands[$i] = $operand = '(' . join( ' OR ', map { 'nb=' . $_ } @isbns ) . ')';
+ $indexes[$i] = $index = 'kw';
+ }
+ }
+ if ( $index eq 'ns' ) {
+ if ( C4::Context->preference("SearchWithISSNVariations") ) {
+ my @issns = C4::Koha::GetVariationsOfISSN( $operand );
+ $operands[$i] = $operand = '(' . join( ' OR ', map { 'ns=' . $_ } @issns ) . ')';
$indexes[$i] = $index = 'kw';
}
}
}
Koha::Logger->get->debug("QUERY BEFORE LIMITS: >$query<");
- # add limits
- my %group_OR_limits;
- my $availability_limit;
- foreach my $this_limit (@limits) {
- next unless $this_limit;
- if ( $this_limit =~ /available/ ) {
-#
-## 'available' is defined as (items.onloan is NULL) and (items.itemlost = 0)
-## In English:
-## all records not indexed in the onloan register (zebra) and all records with a value of lost equal to 0
- $availability_limit .=
-"( (allrecords,AlwaysMatches='') and (not-onloan-count,st-numeric >= 1) and (lost,st-numeric=0) )";
- $limit_cgi .= "&limit=available";
- $limit_desc .= "";
- }
-
- # group_OR_limits, prefixed by mc-
- # OR every member of the group
- elsif ( $this_limit =~ /mc/ ) {
- my ($k,$v) = split(/:/, $this_limit,2);
- if ( $k !~ /mc-i(tem)?type/ ) {
- # in case the mc-ccode value has complicating chars like ()'s inside it we wrap in quotes
- $this_limit =~ tr/"//d;
- $this_limit = $k.':"'.$v.'"';
- }
-
- $group_OR_limits{$k} .= " or " if $group_OR_limits{$k};
- $limit_desc .= " or " if $group_OR_limits{$k};
- $group_OR_limits{$k} .= "$this_limit";
- $limit_cgi .= "&limit=" . uri_escape_utf8($this_limit);
- $limit_desc .= " $this_limit";
- }
- elsif ( $this_limit =~ '^multibranchlimit:|^branch:' ) {
- $limit_cgi .= "&limit=" . uri_escape_utf8($this_limit);
- $limit .= " and " if $limit || $query;
- my $branchfield = C4::Context->preference('SearchLimitLibrary');
- my @branchcodes;
- if( $this_limit =~ '^multibranchlimit:' ){
- my ($group_id) = ( $this_limit =~ /^multibranchlimit:(.*)$/ );
- my $search_group = Koha::Library::Groups->find( $group_id );
- @branchcodes = map { $_->branchcode } $search_group->all_libraries;
- @branchcodes = sort { $a cmp $b } @branchcodes;
- } else {
- @branchcodes = ( $this_limit =~ /^branch:(.*)$/ );
- }
-
- if (@branchcodes) {
- if ( $branchfield eq "homebranch" ) {
- $this_limit = sprintf "(%s)", join " or ", map { 'homebranch: ' . $_ } @branchcodes;
- }
- elsif ( $branchfield eq "holdingbranch" ) {
- $this_limit = sprintf "(%s)", join " or ", map { 'holdingbranch: ' . $_ } @branchcodes;
- }
- else {
- $this_limit = sprintf "(%s or %s)",
- join( " or ", map { 'homebranch: ' . $_ } @branchcodes ),
- join( " or ", map { 'holdingbranch: ' . $_ } @branchcodes );
- }
- }
- $limit .= "$this_limit";
- $limit_desc .= " $this_limit";
- }
-
- # Regular old limits
- else {
- $limit .= " and " if $limit || $query;
- $limit .= "$this_limit";
- $limit_cgi .= "&limit=" . uri_escape_utf8($this_limit);
- $limit_desc .= " $this_limit";
- }
- }
- foreach my $k (keys (%group_OR_limits)) {
- $limit .= " and " if ( $query || $limit );
- $limit .= "($group_OR_limits{$k})";
- }
- if ($availability_limit) {
- $limit .= " and " if ( $query || $limit );
- $limit .= "($availability_limit)";
- }
-
# Normalize the query and limit strings
# 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
: GetFrameworkCode($marcrecord->subfield($bibliotag,$bibliosubf));
SetUTF8Flag($marcrecord);
- my $oldbiblio = TransformMarcToKoha( $marcrecord, $fw, 'no_items' );
+ my $oldbiblio = TransformMarcToKoha({ record => $marcrecord, limit_table => 'no_items' });
$oldbiblio->{result_number} = $i + 1;
$oldbiblio->{normalized_upc} = GetNormalizedUPC( $marcrecord,$marcflavour);
foreach my $code ( keys %subfieldstosearch ) {
$item->{$code} = $field->subfield( $subfieldstosearch{$code} );
}
+
+ unless ( $item->{itemnumber} ) {
+ warn "MARC item without itemnumber retrieved for biblio ($oldbiblio->{biblionumber})";
+ next;
+ }
+
$item->{description} = $itemtypes{ $item->{itype} }{translated_description} if $item->{itype};
- # OPAC hidden items
+ # OPAC hidden items
if ($is_opac) {
- # hidden because lost
- if ($hidelostitems && $item->{itemlost}) {
+ # hidden based on OpacHiddenItems syspref or because lost
+ my $hi = Koha::Items->search( { itemnumber => $item->{itemnumber} } )
+ ->filter_by_visible_in_opac({ patron => $search_context->{patron} });
+ unless ( $hi->count ) {
push @hiddenitems, $item->{itemnumber};
$hideatopac_count++;
next;
}
- # hidden based on OpacHiddenItems syspref
- my @hi = C4::Items::GetHiddenItemnumbers({ items=> [ $item ], borcat => $search_context->{category} });
- if (scalar @hi) {
- push @hiddenitems, @hi;
- $hideatopac_count++;
- next;
- }
}
my $hbranch = C4::Context->preference('StaffSearchResultsDisplayBranch');
# FIXME: to avoid having the query the database like this, and to make
# the in transit status count as unavailable for search limiting,
# should map transit status to record indexed in Zebra.
- #
- ($transfertwhen, $transfertfrom, $transfertto) = C4::Circulation::GetTransfers($item->{itemnumber});
+
+ my $item_object = Koha::Items->find($item->{itemnumber});
+ my $transfer = defined($item_object) ? $item_object->get_transfer : undef;
+ ( $transfertwhen, $transfertfrom, $transfertto ) =
+ defined($transfer)
+ ? (
+ $transfer->datesent, $transfer->frombranch,
+ $transfer->tobranch
+ )
+ : ( '', '', '' );
$reservestatus = C4::Reserves::GetReserveStatus( $item->{itemnumber} );
if ( C4::Context->preference('UseRecalls') ) {
if ( Koha::Recalls->search({ item_id => $item->{itemnumber}, status => 'waiting' })->count ) {
),
fix_amps => 1,
hidden_items => \@hiddenitems,
- xslt_variables => $xslt_variables
+ xslt_variables => $xslt_variables,
}
);
}
my $biblio_object = Koha::Biblios->find( $oldbiblio->{biblionumber} );
$oldbiblio->{biblio_object} = $biblio_object;
+ $oldbiblio->{coins} = eval { $biblio_object->get_coins }
+ if $biblio_object
+ && C4::Context->preference('COinSinOPACResults')
+ && $is_opac;
my $can_place_holds = 1;
# if biblio level itypes are used and itemtype is notforloan, it can't be reserved either