Bug 35142: Migrate callers to use metadata extractor

Replaces all calls to GetNormalizedOCLCNumber() and
Koha::Util::MARC::oclc_number() with the extractor pattern.

OPAC scripts pass their already ViewPolicy-filtered $record directly
to the extractor. This preserves the existing filtering behavior
without introducing new abstraction layers:

    Koha::Biblio::Metadata::Extractor->new( { metadata => $record } )->get_normalized_oclc

Intranet scripts and the Koha::Biblio convenience method use the
raw cached extractor (035 visibility is not affected by ViewPolicy
in practice, and intranet doesn't filter):

    $biblio->normalized_oclc

Test plan:
1. Verify OCLC numbers display on OPAC detail, ISBD, MARC detail
2. Verify staff catalogue detail and search results
3. prove t/db_dependent/Koha/Biblio.t

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Assisted-by: Sonnet 4.6 (Anthropic)
Signed-off-by: David Nind <david@davidnind.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
Tomás Cohen Arazi 2026-06-19 17:35:21 -03:00 committed by Pedro Amorim
parent 6b77f28dd7
commit 263a1bd536
No known key found for this signature in database
GPG Key ID: 06B75BA7F3894D55
12 changed files with 41 additions and 42 deletions

View File

@ -36,7 +36,8 @@ BEGIN {
use C4::Context;
use C4::Biblio qw( TransformMarcToKoha GetMarcFromKohaField GetFrameworkCode GetAuthorisedValueDesc GetBiblioData );
use C4::Koha
qw( getFacets GetVariationsOfISBN GetNormalizedUPC GetNormalizedEAN GetNormalizedOCLCNumber GetNormalizedISBN getitemtypeimagelocation );
qw( getFacets GetVariationsOfISBN GetNormalizedUPC GetNormalizedEAN GetNormalizedISBN getitemtypeimagelocation );
use Koha::Biblio::Metadata::Extractor;
use Koha::DateUtils;
use Koha::Libraries;
use Koha::SearchEngine::QueryBuilder;
@ -1768,9 +1769,10 @@ sub searchResults {
my $oldbiblio = TransformMarcToKoha( { record => $marcrecord, limit_table => 'no_items' } );
$oldbiblio->{result_number} = $i + 1;
$oldbiblio->{normalized_upc} = GetNormalizedUPC( $marcrecord, $marcflavour );
$oldbiblio->{normalized_ean} = GetNormalizedEAN( $marcrecord, $marcflavour );
$oldbiblio->{normalized_oclc} = GetNormalizedOCLCNumber( $marcrecord, $marcflavour );
$oldbiblio->{normalized_upc} = GetNormalizedUPC( $marcrecord, $marcflavour );
$oldbiblio->{normalized_ean} = GetNormalizedEAN( $marcrecord, $marcflavour );
$oldbiblio->{normalized_oclc} =
Koha::Biblio::Metadata::Extractor->new( { metadata => $marcrecord } )->get_normalized_oclc;
$oldbiblio->{normalized_isbn} = GetNormalizedISBN( $oldbiblio->{isbn}, $marcrecord, $marcflavour )
; # Use existing ISBN from record if we got one
$oldbiblio->{content_identifier_exists} = 1

View File

@ -28,7 +28,8 @@ BEGIN {
use C4::Biblio qw( GetAuthorisedValueDesc );
use C4::Context;
use C4::Koha qw( GetNormalizedUPC GetNormalizedOCLCNumber GetNormalizedISBN GetNormalizedEAN );
use C4::Koha qw( GetNormalizedUPC GetNormalizedISBN GetNormalizedEAN );
use Koha::Biblio::Metadata::Extractor;
use Koha::Biblios;
use Koha::Libraries;
@ -235,8 +236,9 @@ sub GetShelfInfo {
$item->{part_number} = $biblio->part_number;
$item->{part_name} = $biblio->part_name;
my $this_record = $biblio->metadata->record;
$item->{'browser_normalized_upc'} = GetNormalizedUPC( $this_record, $marcflavour );
$item->{'browser_normalized_oclc'} = GetNormalizedOCLCNumber( $this_record, $marcflavour );
$item->{'browser_normalized_upc'} = GetNormalizedUPC( $this_record, $marcflavour );
$item->{'browser_normalized_oclc'} =
Koha::Biblio::Metadata::Extractor->new( { metadata => $this_record } )->get_normalized_oclc;
$item->{'browser_normalized_isbn'} = GetNormalizedISBN( undef, $this_record, $marcflavour );
$item->{'browser_normalized_ean'} = GetNormalizedEAN( $this_record, $marcflavour );
push @valid_items, $item;

View File

@ -25,7 +25,7 @@ use URI;
use URI::Escape qw( uri_escape_utf8 );
use Try::Tiny;
use C4::Koha qw( GetNormalizedISBN GetNormalizedUPC GetNormalizedOCLCNumber );
use C4::Koha qw( GetNormalizedISBN );
use C4::Biblio qw( DelBiblio );
use C4::Serials qw( CountSubscriptionFromBiblionumber );
use C4::Reserves qw( MergeHolds );

View File

@ -25,7 +25,6 @@ use C4::Koha qw(
getitemtypeimagelocation
GetNormalizedEAN
GetNormalizedISBN
GetNormalizedOCLCNumber
GetNormalizedUPC
);
use C4::Serials qw( CountSubscriptionFromBiblionumber SearchSubscriptions GetLatestSerials );
@ -171,7 +170,7 @@ $template->param( ocoins => !$invalid_marc_record ? $biblio->get_coins : undef )
# the record and normalizing it
my $upc = GetNormalizedUPC( $marc_record, $marcflavour );
my $ean = GetNormalizedEAN( $marc_record, $marcflavour );
my $oclc = GetNormalizedOCLCNumber( $marc_record, $marcflavour );
my $oclc = $biblio->normalized_oclc;
my $isbn = GetNormalizedISBN( undef, $marc_record, $marcflavour );
my $content_identifier_exists;
if ( $isbn or $ean or $oclc or $upc ) {

View File

@ -56,7 +56,6 @@ use C4::Serials qw( CountSubscriptionFromBiblionumber SearchSubscriptions GetLa
use C4::Koha qw(
GetNormalizedEAN
GetNormalizedISBN
GetNormalizedOCLCNumber
GetNormalizedUPC
);
use Koha::CirculationRules;
@ -106,7 +105,6 @@ unless ( $patron and $patron->category->override_hidden_items ) {
my $record = $biblio->metadata->record;
my @items = $biblio->items->filter_by_visible_in_opac( { patron => $patron } )->as_list;
my $metadata_extractor = $biblio->metadata_extractor;
my $record_processor = Koha::RecordProcessor->new(
{
@ -119,6 +117,7 @@ my $record_processor = Koha::RecordProcessor->new(
}
);
$record_processor->process($record);
my $extractor = Koha::Biblio::Metadata::Extractor->new( { metadata => $record } );
# get biblionumbers stored in the cart
if ( my $cart_list = $query->cookie("bib_list") ) {
@ -135,7 +134,7 @@ my $marcflavour = C4::Context->preference("marcflavour");
# the record and normalizing it
my $upc = GetNormalizedUPC( $record, $marcflavour );
my $ean = GetNormalizedEAN( $record, $marcflavour );
my $oclc = GetNormalizedOCLCNumber( $record, $marcflavour );
my $oclc = $extractor->get_normalized_oclc;
my $isbn = GetNormalizedISBN( undef, $record, $marcflavour );
my $content_identifier_exists;
if ( $isbn or $ean or $oclc or $upc ) {
@ -205,14 +204,14 @@ $template->param(
);
#Search for title in links
my $control_number = $metadata_extractor->get_control_number();
my $control_number = $extractor->get_control_number();
my $marcissns = GetMarcISSN( $record, $marcflavour );
my $issn = $marcissns->[0] || '';
if ( my $search_for_title = C4::Context->preference('OPACSearchForTitleIn') ) {
$dat->{title} =~ s/\/+$//; # remove trailing slash
$dat->{title} =~ s/\s+$//; # remove trailing space
my $oclc_no = Koha::Util::MARC::oclc_number($record);
my $oclc_no = $extractor->get_normalized_oclc;
$search_for_title = parametrized_url(
$search_for_title,
{

View File

@ -341,7 +341,7 @@ my $issn = $marcissns->[0] || '';
if ( my $search_for_title = C4::Context->preference('OPACSearchForTitleIn') ) {
$dat->{title} =~ s/\/+$//; # remove trailing slash
$dat->{title} =~ s/\s+$//; # remove trailing space
my $oclc_no = Koha::Util::MARC::oclc_number($record);
my $oclc_no = $metadata_extractor->get_normalized_oclc;
$search_for_title = parametrized_url(
$search_for_title,
{

View File

@ -28,7 +28,6 @@ use C4::Koha qw(
getitemtypeimagelocation
GetNormalizedEAN
GetNormalizedISBN
GetNormalizedOCLCNumber
GetNormalizedUPC
);
use C4::Search qw( new_record_from_zebra searchResults getRecords );
@ -114,8 +113,6 @@ unless ( $biblio && $record ) {
redirect_if_opac_suppressed( $query, $biblio )
if C4::Context->preference('OpacSuppression');
my $metadata_extractor = $biblio->metadata_extractor;
my $items = $biblio->items->search_ordered;
if ($specific_item) {
$items = $items->search( { itemnumber => scalar $query->param('itemnumber') } );
@ -146,6 +143,7 @@ my $record_processor = Koha::RecordProcessor->new(
}
);
$record_processor->process($record);
my $extractor = Koha::Biblio::Metadata::Extractor->new( { metadata => $record } );
$template->param( biblio => $biblio );
@ -877,7 +875,7 @@ foreach ( keys %{$dat} ) {
# in each case, we're grabbing the first value we find in
# the record and normalizing it
my $upc = GetNormalizedUPC( $record, $marcflavour );
my $oclc = GetNormalizedOCLCNumber( $record, $marcflavour );
my $oclc = $extractor->get_normalized_oclc;
my $isbn = GetNormalizedISBN( undef, $record, $marcflavour );
my $content_identifier_exists;
if ( $isbn or $ean or $oclc or $upc ) {
@ -1171,14 +1169,14 @@ if ( C4::Context->preference('OpacStarRatings') !~ /disable/ ) {
}
#Search for title in links
my $control_number = $metadata_extractor->get_control_number();
my $control_number = $extractor->get_control_number();
my $marcissns = GetMarcISSN( $record, $marcflavour );
my $issn = $marcissns->[0] || '';
if ( my $search_for_title = C4::Context->preference('OPACSearchForTitleIn') ) {
$dat->{title} =~ s/\/+$//; # remove trailing slash
$dat->{title} =~ s/\s+$//; # remove trailing space
my $oclc_no = Koha::Util::MARC::oclc_number($record);
my $oclc_no = $extractor->get_normalized_oclc;
$search_for_title = parametrized_url(
$search_for_title,
{

View File

@ -25,7 +25,6 @@ use C4::Biblio qw( GetBiblioData GetFrameworkCode );
use C4::Koha qw(
GetNormalizedEAN
GetNormalizedISBN
GetNormalizedOCLCNumber
GetNormalizedUPC
);
use C4::Members;
@ -389,10 +388,11 @@ if ( $op eq 'view' ) {
$this_item->{description} = $itemtype->description; #FIXME Should not it be translated_description?
$this_item->{notforloan} = $itemtype->notforloan;
}
$this_item->{'coins'} = $biblio->get_coins;
$this_item->{'normalized_upc'} = GetNormalizedUPC( $record, $marcflavour );
$this_item->{'normalized_ean'} = GetNormalizedEAN( $record, $marcflavour );
$this_item->{'normalized_oclc'} = GetNormalizedOCLCNumber( $record, $marcflavour );
$this_item->{'coins'} = $biblio->get_coins;
$this_item->{'normalized_upc'} = GetNormalizedUPC( $record, $marcflavour );
$this_item->{'normalized_ean'} = GetNormalizedEAN( $record, $marcflavour );
$this_item->{'normalized_oclc'} =
Koha::Biblio::Metadata::Extractor->new( { metadata => $record } )->get_normalized_oclc;
$this_item->{'normalized_isbn'} = GetNormalizedISBN( undef, $record, $marcflavour );
# BZ17530: 'Intelligent' guess if result can be article requested

View File

@ -25,7 +25,6 @@ use C4::Auth qw( get_template_and_user );
use C4::Koha qw(
GetNormalizedEAN
GetNormalizedISBN
GetNormalizedOCLCNumber
GetNormalizedUPC
);
use C4::Output qw( output_html_with_http_headers );
@ -96,7 +95,7 @@ for my $result (@$reviews) {
my $record = $biblio->metadata->record;
$result->{normalized_upc} = GetNormalizedUPC( $record, $marcflavour );
$result->{normalized_ean} = GetNormalizedEAN( $record, $marcflavour );
$result->{normalized_oclc} = GetNormalizedOCLCNumber( $record, $marcflavour );
$result->{normalized_oclc} = Koha::Biblio::Metadata::Extractor->new( { metadata => $record } )->get_normalized_oclc;
$result->{normalized_isbn} = GetNormalizedISBN( undef, $record, $marcflavour );
$result->{title} = $biblio->title;
$result->{subtitle} = $biblio->subtitle;

View File

@ -26,7 +26,6 @@ use C4::Koha qw(
getitemtypeimagelocation
GetNormalizedISBN
GetNormalizedUPC
GetNormalizedOCLCNumber
);
use C4::Circulation qw( CanBookBeRenewed GetRenewCount GetIssuingCharges );
use C4::Reserves qw( GetReserveStatus );
@ -307,8 +306,9 @@ if ( $pending_checkouts->count ) { # Useless test
patron => $patron
}
);
$issue->{normalized_upc} = GetNormalizedUPC( $marcrecord, C4::Context->preference('marcflavour') );
$issue->{normalized_oclc} = GetNormalizedOCLCNumber( $marcrecord, C4::Context->preference('marcflavour') );
$issue->{normalized_upc} = GetNormalizedUPC( $marcrecord, C4::Context->preference('marcflavour') );
$issue->{normalized_oclc} =
Koha::Biblio::Metadata::Extractor->new( { metadata => $marcrecord } )->get_normalized_oclc;
}
if ( C4::Context->preference('UseRecalls') ) {

View File

@ -2040,20 +2040,21 @@ subtest 'normalized_upc() tests' => sub {
};
subtest 'normalized_oclc() tests' => sub {
plan tests => 1;
plan tests => 2;
$schema->storage->txn_begin;
# We will move the tests from GetNormalizedOCLC here when it will get replaced
# Note that only a single test exist and it's not really meaningful...
my $biblio = $builder->build_sample_biblio();
is(
$biblio->normalized_oclc, C4::Koha::GetNormalizedOCLCNumber( $biblio->metadata->record ),
'normalized_oclc is a wrapper around C4::Koha::GetNormalizedOCLCNumber'
);
is( $biblio->normalized_oclc, '', 'normalized_oclc returns empty string when no 035 with OCoLC' );
my $record = $biblio->metadata->record;
$record->append_fields( MARC::Field->new( '035', ' ', ' ', a => '(OCoLC)902632762' ) );
C4::Biblio::ModBiblio( $record, $biblio->biblionumber );
$biblio = Koha::Biblios->find( $biblio->biblionumber );
is( $biblio->normalized_oclc, '902632762', 'normalized_oclc extracts OCLC number' );
$schema->storage->txn_rollback;
};
subtest 'opac_suppressed() tests' => sub {

View File

@ -25,7 +25,6 @@ use C4::Context;
use C4::Koha qw(
GetNormalizedEAN
GetNormalizedISBN
GetNormalizedOCLCNumber
GetNormalizedUPC
);
use C4::Members;
@ -355,7 +354,7 @@ if ( $op eq 'view' ) {
$this_item->{'coins'} = $biblio->get_coins;
$this_item->{'normalized_upc'} = GetNormalizedUPC( $record, $marcflavour );
$this_item->{'normalized_ean'} = GetNormalizedEAN( $record, $marcflavour );
$this_item->{'normalized_oclc'} = GetNormalizedOCLCNumber( $record, $marcflavour );
$this_item->{'normalized_oclc'} = $biblio->normalized_oclc;
$this_item->{'normalized_isbn'} = GetNormalizedISBN( undef, $record, $marcflavour );
unless ( defined $this_item->{size} ) {