From ecfad80842b29509cf294002ad7c33fd8f59e812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joonas=20Kylm=C3=A4l=C3=A4?= Date: Fri, 13 Nov 2020 19:52:18 +0200 Subject: [PATCH] Bug 11175: Limit the amount of component parts returned There was already before this a limit of 100 results when using Elasticsearch but then the list of component parts was truncated silently. This change now limits the amount to hard coded limit of 300 which is still fast to render. Also when the 300 component part record limit is reached there is a link in the list now to list all the records via the cataloging search. To test: 1) Create 300+ component part records and see if the link to list all the component part records shows up 2) Make sure prove t/Koha/Util/Search.t passes Signed-off-by: Pasi Kallinen Signed-off-by: Martin Renvoize --- C4/XSLT.pm | 21 ++++--- Koha/Biblio.pm | 26 ++------- Koha/Util/Search.pm | 57 +++++++++++++++++++ .../prog/en/xslt/MARC21slimUtils.xsl | 6 ++ t/Koha/Util/Search.t | 42 ++++++++++++++ 5 files changed, 125 insertions(+), 27 deletions(-) create mode 100644 Koha/Util/Search.pm create mode 100755 t/Koha/Util/Search.t diff --git a/C4/XSLT.pm b/C4/XSLT.pm index 6b894550fc..5f90c4b49b 100644 --- a/C4/XSLT.pm +++ b/C4/XSLT.pm @@ -31,6 +31,7 @@ use C4::Circulation; use C4::Reserves; use Koha::AuthorisedValues; use Koha::ItemTypes; +use Koha::Util::Search; use Koha::XSLT::Base; use Koha::Libraries; @@ -266,11 +267,6 @@ sub XSLTParse4Display { $variables->{OpenURLResolverURL} = $biblio->get_openurl; } } - my $varxml = "\n"; - while (my ($key, $value) = each %$variables) { - $varxml .= "$value\n"; - } - $varxml .= "\n"; my $partsxml = ''; # possibly insert component records into Detail views @@ -280,9 +276,14 @@ sub XSLTParse4Display { ($showcomp eq 'staff' && $xslsyspref !~ m/OPAC/ ) || ($showcomp eq 'opac' && $xslsyspref =~ m/OPAC/ ) ) { my $biblio = Koha::Biblios->find( $biblionumber ); - if ( $biblio->components() ) { + my $max_results = 300; + + if ( $biblio->components($max_results) ) { + my $search_query = Koha::Util::Search::get_component_part_query($biblionumber); + $variables->{ComponentPartQuery} = $search_query; + my @componentPartRecordXML = (''); - for my $cb ( @{ $biblio->components() } ) { + for my $cb ( @{ $biblio->components($max_results) } ) { if( ref $cb eq 'MARC::Record'){ $cb = $cb->as_xml_record(); } else { @@ -298,6 +299,12 @@ sub XSLTParse4Display { } } + my $varxml = "\n"; + while (my ($key, $value) = each %$variables) { + $varxml .= "$value\n"; + } + $varxml .= "\n"; + $xmlrecord =~ s/\<\/record\>/$itemsxml$sysxml$varxml$partsxml\<\/record\>/; if ($fixamps) { # We need to correct the ampersand entities that Zebra outputs $xmlrecord =~ s/\&amp;/\&/g; diff --git a/Koha/Biblio.pm b/Koha/Biblio.pm index 3a96f437f1..73c8385782 100644 --- a/Koha/Biblio.pm +++ b/Koha/Biblio.pm @@ -45,6 +45,7 @@ use Koha::Suggestions; use Koha::Subscriptions; use Koha::SearchEngine; use Koha::SearchEngine::Search; +use Koha::Util::Search; =head1 NAME @@ -509,31 +510,16 @@ this object (MARC21 773$w points to this) =cut sub components { - my ($self) = @_; + my ($self, $max_results) = @_; return if (C4::Context->preference('marcflavour') ne 'MARC21'); - my $marc = C4::Biblio::GetMarcBiblio({ biblionumber => $self->id }); - my $pf001 = $marc->field('001') || undef; - my $searcher = Koha::SearchEngine::Search->new({index => $Koha::SearchEngine::BIBLIOS_INDEX}); - - if (defined($pf001)) { - my $pf003 = $marc->field('003') || undef; - my $searchstr; - - if (!defined($pf003)) { - # search for 773$w='Host001' - $searchstr = "rcn='".$pf001->data()."'"; - } else { - # search for (773$w='Host001' and 003='Host003') or 773$w='Host003 Host001') - $searchstr = "(rcn='".$pf001->data()."' AND cni='".$pf003->data()."')"; - $searchstr .= " OR rcn='".$pf003->data()." ".$pf001->data()."'"; - } + my $searchstr = Koha::Util::Search::get_component_part_query($self->id); - my ( $errors, $results, $total_hits ) = $searcher->simple_search_compat( $searchstr, 0, undef ); + if (defined($searchstr)) { + my $searcher = Koha::SearchEngine::Search->new({index => $Koha::SearchEngine::BIBLIOS_INDEX}); + my ( $errors, $results, $total_hits ) = $searcher->simple_search_compat( $searchstr, 0, $max_results ); $self->{_components} = $results if ( defined($results) && scalar(@$results) ); - } else { - warn "Record $self->id has no 001"; } return $self->{_components} || (); diff --git a/Koha/Util/Search.pm b/Koha/Util/Search.pm new file mode 100644 index 0000000000..4e1c9706a8 --- /dev/null +++ b/Koha/Util/Search.pm @@ -0,0 +1,57 @@ +package Koha::Util::Search; + +# Copyright 2020 University of Helsinki +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use C4::Biblio; + +=head1 NAME + +Koha::Util::Search – functions to build complex search queries + +=head1 FUNCTIONS + +=head2 get_component_part_query + +Returns a query which can be used to search for all component parts of MARC21 biblios + +=cut + +sub get_component_part_query { + my ($biblionumber) = @_; + + my $marc = C4::Biblio::GetMarcBiblio({ biblionumber => $biblionumber }); + my $pf001 = $marc->field('001') || undef; + + if (defined($pf001)) { + my $pf003 = $marc->field('003') || undef; + my $searchstr; + + if (!defined($pf003)) { + # search for 773$w='Host001' + $searchstr = "rcn='".$pf001->data()."'"; + } else { + # search for (773$w='Host001' and 003='Host003') or 773$w='Host003 Host001') + $searchstr = "(rcn='".$pf001->data()."' AND cni='".$pf003->data()."')"; + $searchstr .= " OR rcn='".$pf003->data()." ".$pf001->data()."'"; + } + } +} + +1; diff --git a/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slimUtils.xsl b/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slimUtils.xsl index 7a0d708d91..f947d4ade9 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slimUtils.xsl +++ b/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slimUtils.xsl @@ -581,6 +581,7 @@ +
Component part records
    @@ -640,6 +641,11 @@
+ + +

Only 300 results are shown: /cgi-bin/koha/catalogue/search.pl?q=show all component parts

+
+
diff --git a/t/Koha/Util/Search.t b/t/Koha/Util/Search.t new file mode 100755 index 0000000000..c56b9404e2 --- /dev/null +++ b/t/Koha/Util/Search.t @@ -0,0 +1,42 @@ +#!/usr/bin/perl +# +# Copyright 2020 University of Helsinki +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Test::More tests => 1; +use t::lib::TestBuilder; + +use C4::Biblio; +use Koha::Util::Search; +use MARC::Field; + +my $builder = t::lib::TestBuilder->new; + +subtest 'get_component_part_query' => sub { + plan tests => 1; + + my $biblio = $builder->build_sample_biblio(); + my $biblionumber = $biblio->biblionumber; + my $record = GetMarcBiblio({ biblionumber => $biblionumber }); + my $marc_001_field = MARC::Field->new('001', $biblionumber); + $record->append_fields($marc_001_field); + ModBiblioMarc($record, $biblionumber); + + is(Koha::Util::Search::get_component_part_query($biblionumber), "rcn='$biblionumber'"); +}; -- 2.20.1