Bugzilla – Attachment 127591 Details for
Bug 29268
Query used in Koha::Biblio->get_marc_host is incorrect
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 29268: Correct cni handling for get_marc_host
Bug-29268-Correct-cni-handling-for-getmarchost.patch (text/plain), 9.20 KB, created by
Martin Renvoize (ashimema)
on 2021-11-12 16:48:45 UTC
(
hide
)
Description:
Bug 29268: Correct cni handling for get_marc_host
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2021-11-12 16:48:45 UTC
Size:
9.20 KB
patch
obsolete
>From d5a511f793de5d76cae0ba7c869d60a2f84edeb3 Mon Sep 17 00:00:00 2001 >From: Martin Renvoize <martin.renvoize@ptfs-europe.com> >Date: Tue, 19 Oct 2021 11:40:45 +0100 >Subject: [PATCH] Bug 29268: Correct cni handling for get_marc_host > >This patch adds a new method for fetching an ordered list of search >queries that can then be used to fetch a records host biblio. >--- > Koha/Biblio.pm | 146 +++++++++++++++++------ > t/db_dependent/Koha/Biblio.t | 33 ++++- > t/db_dependent/Koha/Biblio/host_record.t | 1 + > 3 files changed, 144 insertions(+), 36 deletions(-) > >diff --git a/Koha/Biblio.pm b/Koha/Biblio.pm >index c4c12128af..aa0c3325b4 100644 >--- a/Koha/Biblio.pm >+++ b/Koha/Biblio.pm >@@ -1019,53 +1019,129 @@ sub to_api_mapping { > =cut > > sub get_marc_host { >- my ($self, $params) = @_; >+ my ( $self, $params ) = @_; > my $no_items = $params->{no_items}; >- return if C4::Context->preference('marcflavour') eq 'UNIMARC'; # TODO >+ return if C4::Context->preference('marcflavour') eq 'UNIMARC'; # TODO > return if $params->{no_items} && $self->items->count > 0; > >- my $record; >- eval { $record = $self->metadata->record }; >- return if !$record; >+ my ( $bibno, $hostfld ); >+ my $engine = Koha::SearchEngine::Search->new( >+ { index => $Koha::SearchEngine::BIBLIOS_INDEX } ); > >- # We pick the first $w with your MARCOrgCode or the first $w that has no >- # code (between parentheses) at all. >- my $orgcode = C4::Context->preference('MARCOrgCode') // q{}; >- my $hostfld; >- foreach my $f ( $record->field('773') ) { >- my $w = $f->subfield('w') or next; >- if( $w =~ /^\($orgcode\)\s*(\d+)/i or $w =~ /^\d+/ ) { >- $hostfld = $f; >- last; >- } >- } >- return if !$hostfld; >- my $rcn = $hostfld->subfield('w'); >- >- # Look for control number with/without orgcode >- my $engine = Koha::SearchEngine::Search->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX }); >- my $bibno; >- for my $try (1..2) { >- my ( $error, $results, $total_hits ) = $engine->simple_search_compat( 'Control-number='.$rcn, 0,1 ); >- if( !$error and $total_hits == 1 ) { >- $bibno = $engine->extract_biblionumber( $results->[0] ); >- last; >- } >- # Add or remove orgcode for second try >- if( $try == 1 && $rcn =~ /\)\s*(\d+)/ ) { >- $rcn = $1; # number only >- } elsif( $try == 1 && $rcn =~ /^\d+/ ) { >- $rcn = "($orgcode)$rcn"; >- } else { >+ # Search for host with/without orgcode >+ my $queries = $self->get_host_queries; >+ for my $query ( @{$queries} ) { >+ my ( $error, $results, $total_hits ) = >+ $engine->simple_search_compat( $query->{query}, 0, 1 ); >+ >+ if ( !$error and $total_hits == 1 ) { >+ $bibno = $engine->extract_biblionumber( $results->[0] ); >+ $hostfld = $query->{field}; > last; > } > } >- if( $bibno ) { >+ >+ if ($bibno) { > my $host = Koha::Biblios->find($bibno) or return; > return wantarray ? ( $host, $hostfld->subfield('g') ) : $host; > } > } > >+=head2 get_host_queries >+ >+Returns an array of queries which can be used to search for the host of this MARC21 biblio. >+ >+The array is in most specific to least specific search order. >+ >+The algorithm used to construct the search query is: >+1. Iterate through all `773` fields. >+2. If using 'UseControlNumber' iterate through each `w` subfield. >+2a. Best match is where the $w contains `(cni)cn` and the cni matches our orgcode. >+2b. Next best match is where $w contains `(cni)cn` and the cni does not match our orgcode. >+2c. Subsequent matches are where $w contains just `cn` >+3. If not using 'UseControlNumber' we search on title and author >+ >+=cut >+ >+sub get_host_queries { >+ my ($self) = @_; >+ >+ my $record = $self->metadata->record; >+ >+ my $builder = Koha::SearchEngine::QueryBuilder->new( >+ { index => $Koha::SearchEngine::BIBLIOS_INDEX } ); >+ my $cni_queries = []; >+ my $cn_queries = []; >+ my $ti_queries = []; >+ >+ my $orgcode = C4::Context->preference('MARCOrgCode') // q{}; >+ foreach my $f ( $record->field('773') ) { >+ if ( C4::Context->preference('UseControlNumber') ) { >+ foreach my $w ( $f->subfield('w') ) { >+ >+ # Control-number-identifier prepended >+ if ( $w =~ /^\((?<cni>.*)\)\s*(?<cn>\d+)/i ) { >+ >+ # Local orgcode match >+ if ( $+{cni} eq $orgcode ) { >+ my $query = >+ "(Control-number:" >+ . $+{cn} >+ . " AND cni:" >+ . $+{cni} . ")"; >+ unshift( >+ @{$cni_queries}, >+ { query => $query, field => $f } >+ ); >+ } >+ >+ # Other orgcodes >+ else { >+ my $query = >+ "(Control-number:" >+ . $+{cn} >+ . " AND cni:" >+ . $+{cni} . ")"; >+ push( >+ @{$cni_queries}, >+ { >+ query => $query, >+ field => $f >+ } >+ ); >+ } >+ } >+ >+ # Control-number only >+ elsif ( $w =~ /^(?<cn>\d+)/ ) { >+ my $query = "(Control-number:" . $+{cn} . ")"; >+ push( >+ @{$cn_queries}, >+ { >+ query => $query, >+ field => $f >+ } >+ ); >+ } >+ } >+ } >+ else { >+ my $searchstr; >+ my $cleaned_title = $f->subfield('t'); >+ $cleaned_title =~ tr|/||; >+ $cleaned_title = $builder->clean_search_term($cleaned_title); >+ $searchstr = "ti,phr:($cleaned_title)"; >+ my $cleaned_author = $f->subfield('a'); >+ $cleaned_author =~ tr|/||; >+ $cleaned_author = $builder->clean_search_term($cleaned_author); >+ $searchstr .= " AND au:($cleaned_author)" if $cleaned_author; >+ push( @{$ti_queries}, { query => $searchstr, field => $f } ); >+ } >+ } >+ >+ return [ @{$cni_queries}, @{$cn_queries}, @{$ti_queries} ]; >+} >+ > =head2 Internal methods > > =head3 type >diff --git a/t/db_dependent/Koha/Biblio.t b/t/db_dependent/Koha/Biblio.t >index 73dcb2ab13..44de5913e6 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 => 19; >+use Test::More tests => 20; > use Test::Warn; > > use C4::Biblio qw( AddBiblio ModBiblio ModBiblioMarc ); >@@ -564,6 +564,37 @@ subtest 'get_marc_components() tests' => sub { > $schema->storage->txn_rollback; > }; > >+subtest 'get_host_queries' => sub { >+ plan tests => 4; >+ >+ my $biblio = $builder->build_sample_biblio(); >+ my $biblionumber = $biblio->biblionumber; >+ my $record = $biblio->metadata->record; >+ >+ my $marc_773_field = MARC::Field->new('773', '0', '#', 'a' => 'J. K Rowling', 't' => 'The Tales of Beedle the Bard', 'w' => '12345' ); >+ $record->append_fields($marc_773_field); >+ C4::Biblio::ModBiblio( $record, $biblio->biblionumber ); >+ $biblio = Koha::Biblios->find( $biblio->biblionumber); >+ >+ t::lib::Mocks::mock_preference( 'UseControlNumber', '0' ); >+ my $queries = $biblio->get_host_queries; >+ is($queries->[0]->{query}, "ti,phr:(The Tales of Beedle the Bard) AND au:(J. K Rowling)", "UseControlNumber disabled"); >+ >+ t::lib::Mocks::mock_preference( 'UseControlNumber', '1' ); >+ >+ $queries = $biblio->get_host_queries; >+ is($queries->[0]->{query}, "(Control-number:12345)", "UseControlNumber enabled without MarcOrgCode"); >+ >+ $marc_773_field = MARC::Field->new('773', '0', '#', 'a' => 'J. K Rowling', 't' => 'The Tales of Beedle the Bard', 'w' => '(OSt)23456' ); >+ $record->append_fields($marc_773_field); >+ C4::Biblio::ModBiblio( $record, $biblio->biblionumber ); >+ $biblio = Koha::Biblios->find( $biblio->biblionumber); >+ >+ $queries = $biblio->get_host_queries; >+ is($queries->[0]->{query}, "(Control-number:23456 AND cni:OSt)", "UseControlNumber enabled with MarcOrgCode comes out first"); >+ is($queries->[1]->{query}, "(Control-number:12345)", "UseControlNumber enabled without MarcOrgCode comes out second"); >+}; >+ > subtest 'get_components_query' => sub { > plan tests => 3; > >diff --git a/t/db_dependent/Koha/Biblio/host_record.t b/t/db_dependent/Koha/Biblio/host_record.t >index 505efe0b95..48ed75ef4a 100755 >--- a/t/db_dependent/Koha/Biblio/host_record.t >+++ b/t/db_dependent/Koha/Biblio/host_record.t >@@ -40,6 +40,7 @@ subtest 'get_marc_host' => sub { > > t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' ); > t::lib::Mocks::mock_preference( 'MARCOrgCode', 'xyz' ); >+ t::lib::Mocks::mock_preference( 'UseControlNumber', '1' ); > > my $bib1 = $builder->build_object({ class => 'Koha::Biblios' }); > my $bib2 = $builder->build_object({ class => 'Koha::Biblios' }); >-- >2.20.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 29268
:
127590
| 127591