From 9772374290471515ac495ab6dab8116302d0710b Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Wed, 27 Oct 2021 08:50:47 +0100 Subject: [PATCH] Bug 26314: Update for changes to bug 11175 methodology This moves the show_volumes calculation back out of C4::XSLT into the controller scripts and refined the search query builder slightly based on the XSLT equivilent. Signed-off-by: Michaela Sieber --- C4/XSLT.pm | 7 -- Koha/Biblio.pm | 159 +++++++++++++++++++---------------- catalogue/detail.pl | 8 +- opac/opac-detail.pl | 4 + t/db_dependent/Koha/Biblio.t | 11 ++- 5 files changed, 106 insertions(+), 83 deletions(-) diff --git a/C4/XSLT.pm b/C4/XSLT.pm index c328b2f2fc..6a10206359 100644 --- a/C4/XSLT.pm +++ b/C4/XSLT.pm @@ -224,13 +224,6 @@ sub XSLTParse4Display { } } - # possibly show volumes link in Detail views - if ($xslsyspref =~ m/Details/) { - $biblio //= Koha::Biblios->find( $biblionumber ); - my $volumes = $biblio->get_marc_volumes(); - $variables->{show_volumes_link} = ( scalar @{$volumes} == 0 ) ? 0 : 1; - } - # embed variables my $varxml = "\n"; while (my ($key, $value) = each %$variables) { diff --git a/Koha/Biblio.pm b/Koha/Biblio.pm index 55cee02a50..3e3e0f0759 100644 --- a/Koha/Biblio.pm +++ b/Koha/Biblio.pm @@ -715,6 +715,92 @@ sub get_components_query { return ($query, $query_str, $sort); } +=head3 get_marc_volumes + + my $volumes = $self->get_marc_volumes(); + +Returns an array of MARCXML data, which are volumes parts of +this object (MARC21 773$w points to this) + +=cut + +sub get_marc_volumes { + my ( $self, $max_results ) = @_; + + return $self->{_volumes} if defined( $self->{_volumes} ); + + my $searchstr = $self->get_volumes_query; + + 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->{_volumes} = + ( defined($results) && scalar(@$results) ) ? $results : []; + } else { + $self->{_volumes} = []; + } + + return $self->{_volumes}; +} + +=head2 get_volumes_query + +Returns a query which can be used to search for all component parts of MARC21 biblios + +=cut + +sub get_volumes_query { + my ($self) = @_; + + # MARC21 Only for now + return if ( C4::Context->preference('marcflavour') ne 'MARC21' ); + + my $marc = $self->metadata->record; + + # Only build volumes query if we're in a 'Set' record + # or we have a monographic series. + my $leader19 = substr( $marc->leader, 19, 1 ); + my $pf008 = $marc->field('008') || ''; + my $mseries = ( $pf008 && substr( $pf008->data(), 21, 1 ) eq 'm' ) ? 1 : 0; + return unless ( $leader19 eq 'a' || $mseries ); + + my $builder = Koha::SearchEngine::QueryBuilder->new( { index => $Koha::SearchEngine::BIBLIOS_INDEX } ); + + my $searchstr; + if ( C4::Context->preference('UseControlNumber') ) { + my $pf001 = $marc->field('001') || undef; + + if ( defined($pf001) ) { + $searchstr = "("; + my $pf003 = $marc->field('003') || undef; + + if ( !defined($pf003) ) { + + # search for 773$w='Host001' + $searchstr .= "rcn:" . $pf001->data(); + } else { + $searchstr .= "("; + + # 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() . "\""; + $searchstr .= ")"; + } + + # exclude monograph and serial component part records + $searchstr .= " NOT (bib-level:a OR bib-level:b)"; + $searchstr .= ")"; + } + } else { + my $cleaned_title = $marc->subfield( '245', "a" ); + $cleaned_title =~ tr|/||; + $cleaned_title = $builder->clean_search_term($cleaned_title); + $searchstr = "ti,phr:($cleaned_title)"; + } + + return $searchstr; +} + =head3 subscriptions my $subscriptions = $self->subscriptions @@ -1615,79 +1701,6 @@ sub opac_summary_html { return $summary_html; } -=head3 get_marc_volumes - - my $volumes = $self->get_marc_volumes(); - -Returns an array of MARCXML data, which are volumes parts of -this object (MARC21 773$w points to this) - -=cut - -sub get_marc_volumes { - my ($self, $max_results) = @_; - - return [] if (C4::Context->preference('marcflavour') ne 'MARC21'); - - my $searchstr = $self->get_volumes_query; - - 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->{_volumes} = $results if ( defined($results) && scalar(@$results) ); - } - - return $self->{_volumes} || []; -} - -=head2 get_volumes_query - -Returns a query which can be used to search for all component parts of MARC21 biblios - -=cut - -sub get_volumes_query { - my ($self) = @_; - - my $builder = Koha::SearchEngine::QueryBuilder->new( - { index => $Koha::SearchEngine::BIBLIOS_INDEX } ); - my $marc = $self->metadata->record; - - my $searchstr; - if ( C4::Context->preference('UseControlNumber') ) { - my $pf001 = $marc->field('001') || undef; - - if ( defined($pf001) ) { - $searchstr = "("; - my $pf003 = $marc->field('003') || undef; - - if ( !defined($pf003) ) { - # search for 773$w='Host001' - $searchstr .= "rcn:" . $pf001->data(); - } - else { - $searchstr .= "("; - # 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() . "\""; - $searchstr .= ")"; - } - - # exclude monograph and serial component part records - $searchstr .= " NOT (bib-level:a OR bib-level:b)"; - $searchstr .= ")"; - } - } - else { - my $cleaned_title = $marc->subfield('245', "a"); - $cleaned_title =~ tr|/||; - $cleaned_title = $builder->clean_search_term($cleaned_title); - $searchstr = "ti,phr:($cleaned_title)"; - } - - return $searchstr; -} - =head2 Internal methods =head3 type diff --git a/catalogue/detail.pl b/catalogue/detail.pl index 5892acc1d8..085be435b8 100755 --- a/catalogue/detail.pl +++ b/catalogue/detail.pl @@ -269,8 +269,14 @@ if ( $showcomp eq 'both' || $showcomp eq 'staff' ) { $template->param( analytics_error => 1 ) if grep { $_->message eq 'component_search' } @{$biblio->object_messages}; } +# Display volumes link +my $show_volumes = 1 if @{$biblio->get_marc_volumes(1)}; + # XSLT processing of some stuff -my $xslt_variables = { show_analytics_link => $show_analytics }; +my $xslt_variables = { + show_analytics_link => $show_analytics, + show_volumes_link => $show_volumes +}; $template->param( XSLTDetailsDisplay => '1', XSLTBloc => XSLTParse4Display({ diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index 5f5ce3013a..620ceb4945 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -620,6 +620,9 @@ if ( $showcomp eq 'both' || $showcomp eq 'opac' ) { $show_analytics = 1 if @{$biblio->get_marc_components(1)}; # count matters here, results does not } +# Display volumes link +my $show_volumes = 1 if @{$biblio->get_marc_volumes(1)}; + # XSLT processing of some stuff my $variables = {}; my $lang = C4::Languages::getlanguage(); @@ -636,6 +639,7 @@ for my $plugin_variables ( @plugin_responses ) { } $variables->{anonymous_session} = $borrowernumber ? 0 : 1; $variables->{show_analytics_link} = $show_analytics; +$variables->{show_volumes_link} = $show_volumes; $template->param( XSLTBloc => XSLTParse4Display({ biblionumber => $biblionumber, diff --git a/t/db_dependent/Koha/Biblio.t b/t/db_dependent/Koha/Biblio.t index 141d2fdc05..87e917e7af 100755 --- a/t/db_dependent/Koha/Biblio.t +++ b/t/db_dependent/Koha/Biblio.t @@ -622,6 +622,13 @@ subtest 'get_volumes_query' => sub { my $biblionumber = $biblio->biblionumber; my $record = $biblio->metadata->record; + # Ensure our mocked record is captured as a set or monographic series + my $ldr = $record->leader(); + substr( $ldr, 19, 1 ) = 'a'; + $record->leader($ldr); + C4::Biblio::ModBiblio( $record, $biblio->biblionumber ); + $biblio = Koha::Biblios->find( $biblio->biblionumber ); + t::lib::Mocks::mock_preference( 'UseControlNumber', '0' ); is( $biblio->get_volumes_query, "ti,phr:(Some boring read)", "UseControlNumber disabled" ); @@ -632,7 +639,7 @@ subtest 'get_volumes_query' => sub { $biblio = Koha::Biblios->find( $biblio->biblionumber ); is( - $biblio->get_volumes_query, "rcn:$biblionumber NOT (bib-level:a OR bib-level:b)", + $biblio->get_volumes_query, "(rcn:$biblionumber NOT (bib-level:a OR bib-level:b))", "UseControlNumber enabled without MarcOrgCode" ); @@ -643,7 +650,7 @@ subtest 'get_volumes_query' => sub { is( $biblio->get_volumes_query, - "((rcn:$biblionumber AND cni:OSt) OR rcn:OSt $biblionumber) NOT (bib-level:a OR bib-level:b)", + "(((rcn:$biblionumber AND cni:OSt) OR rcn:\"OSt $biblionumber\") NOT (bib-level:a OR bib-level:b))", "UseControlNumber enabled with MarcOrgCode" ); }; -- 2.30.2