From 14d7c9ae881613d3aad7c8b1d1c5122bf5fd9fab Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Mon, 9 Aug 2021 11:39:56 +0100 Subject: [PATCH] Bug 26314: Only display volumes link when required This patch makes C4::XSLT query for volumes the same way it would do with the generated link (i.e. based on UseControlNumber) and passes a flag to the XSLT so it displays (or not) the 'Show volumes' link. To test: 1. Apply the first patch 2. Have a known record without volumes 3. Open the record in the OPAC => FAIL: It shows the 'Show volumes' link 4. Have a record known to have volumes 5. Open the record in the OPAC => SUCCESS: It shows the 'Show volumes' link 6. Apply this patch and restart_all 7. Reload the above records => SUCCESS: It shows the link where it has to, and hides it where it shouldn't be displayed. 8. Repeat for Intranet 9. Sign off :-D --- C4/XSLT.pm | 12 +++- Koha/Biblio.pm | 70 +++++++++++++++++++ .../en/xslt/MARC21slim2intranetDetail.xsl | 3 +- .../en/xslt/MARC21slim2OPACDetail.xsl | 3 +- t/db_dependent/Koha/Biblio.t | 28 +++++++- 5 files changed, 112 insertions(+), 4 deletions(-) diff --git a/C4/XSLT.pm b/C4/XSLT.pm index a96d60b1ec..3770679824 100644 --- a/C4/XSLT.pm +++ b/C4/XSLT.pm @@ -267,9 +267,10 @@ sub XSLTParse4Display { my $xmlrecord = $record->as_xml(C4::Context->preference('marcflavour')); $variables ||= {}; + my $biblio; if (C4::Context->preference('OPACShowOpenURL')) { my @biblio_itemtypes; - my $biblio = Koha::Biblios->find($biblionumber); + $biblio //= Koha::Biblios->find($biblionumber); if (C4::Context->preference('item-level_itypes')) { @biblio_itemtypes = $biblio->items->get_column("itype"); } else { @@ -282,6 +283,15 @@ sub XSLTParse4Display { $variables->{OpenURLResolverURL} = $biblio->get_openurl; } } + + # possibly show volumes link in Detail views + if ($xslsyspref =~ m/Details/) { + $biblio //= Koha::Biblios->find( $biblionumber ); + my $components = $biblio->get_marc_volumes(); + $variables->{show_volumes_link} = ( scalar @{$components} == 0 ) ? 0 : 1; + } + + # embed variables my $varxml = "\n"; while (my ($key, $value) = each %$variables) { $varxml .= "$value\n"; diff --git a/Koha/Biblio.pm b/Koha/Biblio.pm index 26ee7abd96..058e56ba12 100644 --- a/Koha/Biblio.pm +++ b/Koha/Biblio.pm @@ -952,6 +952,76 @@ sub get_marc_host { } } +=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 $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->title; + $cleaned_title =~ tr|/||; + $searchstr = "ti,phr:($cleaned_title)"; + } + + return $searchstr; +} + =head2 Internal methods =head3 type diff --git a/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slim2intranetDetail.xsl b/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slim2intranetDetail.xsl index 49cbd715f6..fd363065c3 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slim2intranetDetail.xsl +++ b/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slim2intranetDetail.xsl @@ -231,7 +231,8 @@ - + + Volumes: diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/xslt/MARC21slim2OPACDetail.xsl b/koha-tmpl/opac-tmpl/bootstrap/en/xslt/MARC21slim2OPACDetail.xsl index 1704004ea1..c5ccf444e7 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/xslt/MARC21slim2OPACDetail.xsl +++ b/koha-tmpl/opac-tmpl/bootstrap/en/xslt/MARC21slim2OPACDetail.xsl @@ -266,7 +266,8 @@ - + + Volumes: diff --git a/t/db_dependent/Koha/Biblio.t b/t/db_dependent/Koha/Biblio.t index 83de0634c6..17290e6733 100755 --- a/t/db_dependent/Koha/Biblio.t +++ b/t/db_dependent/Koha/Biblio.t @@ -17,7 +17,7 @@ use Modern::Perl; -use Test::More tests => 14; +use Test::More tests => 15; use C4::Biblio qw( AddBiblio ModBiblio ); use Koha::Database; @@ -499,6 +499,32 @@ subtest 'suggestions() tests' => sub { $schema->storage->txn_rollback; }; +subtest 'get_volumes_query' => sub { + plan tests => 3; + + my $biblio = $builder->build_sample_biblio(); + my $biblionumber = $biblio->biblionumber; + my $record = $biblio->metadata->record; + + t::lib::Mocks::mock_preference( 'UseControlNumber', '0' ); + is($biblio->get_volumes_query, "ti,phr:(Some boring read)", "UseControlNumber disabled"); + + t::lib::Mocks::mock_preference( 'UseControlNumber', '1' ); + my $marc_001_field = MARC::Field->new('001', $biblionumber); + $record->append_fields($marc_001_field); + C4::Biblio::ModBiblio( $record, $biblio->biblionumber ); + $biblio = Koha::Biblios->find( $biblio->biblionumber); + + is($biblio->get_volumes_query, "rcn:$biblionumber NOT (bib-level:a OR bib-level:b)", "UseControlNumber enabled without MarcOrgCode"); + + my $marc_003_field = MARC::Field->new('003', 'OSt'); + $record->append_fields($marc_003_field); + C4::Biblio::ModBiblio( $record, $biblio->biblionumber ); + $biblio = Koha::Biblios->find( $biblio->biblionumber); + + is($biblio->get_volumes_query, "((rcn:$biblionumber AND cni:OSt) OR rcn:OSt $biblionumber) NOT (bib-level:a OR bib-level:b)", "UseControlNumber enabled with MarcOrgCode"); +}; + subtest 'orders() and active_orders() tests' => sub { plan tests => 5; -- 2.20.1