From 318bea5dbaf5b0376b330135c09821533786b6a5 Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Fri, 2 May 2025 17:06:30 +0100 Subject: [PATCH] Bug 39545: (follow-up) Apply same logic to Koha::Biblio --- Koha/Biblio.pm | 192 ++++++++++++++++++++++++++----------------------- 1 file changed, 103 insertions(+), 89 deletions(-) diff --git a/Koha/Biblio.pm b/Koha/Biblio.pm index 487500de110..30fe29493c1 100644 --- a/Koha/Biblio.pm +++ b/Koha/Biblio.pm @@ -1921,149 +1921,163 @@ sub generate_marc_host_field { my $marcflavour = C4::Context->preference('marcflavour'); my $marc_host = $self->metadata->record; - my %sfd; + + my @sfd; # array of subfields to preserve order my $host_field; my $link_field; if ( $marcflavour eq 'MARC21' ) { - # Author - if ( $host_field = $marc_host->field('100') || $marc_host->field('110') || $marc_host->field('111') ) { - my $s = $host_field->as_string('ab'); - if ($s) { - $sfd{a} = $s; + # Attempt to clone the main entry (100, 110, or 111) + my $main_entry = $marc_host->field('100') || $marc_host->field('110') || $marc_host->field('111'); + $main_entry = $main_entry ? $main_entry->clone : undef; + + # Clean unwanted subfields based on tag type + if ($main_entry) { + if ( $main_entry->tag eq '111' ) { + $main_entry->delete_subfield( code => qr/[94j]/ ); + } else { + $main_entry->delete_subfield( code => qr/[94e]/ ); } } - # Edition - if ( $host_field = $marc_host->field('250') ) { - my $s = $host_field->as_string('ab'); - if ($s) { - $sfd{b} = $s; + # Construct subfield 7 from leader and main entry tag + my $s7 = "nn" . substr( $marc_host->leader, 6, 2 ); + if ($main_entry) { + my $c1 = 'n'; + if ( $main_entry->tag =~ /^1[01]/ ) { + $c1 = $main_entry->indicator('1'); + $c1 = $main_entry->tag eq '100' ? 1 : 2 unless $c1 =~ /\d/; } + my $c0 = + ( $main_entry->tag eq '100' ) ? 'p' + : ( $main_entry->tag eq '110' ) ? 'c' + : ( $main_entry->tag eq '111' ) ? 'm' + : 'u'; + substr( $s7, 0, 2, $c0 . $c1 ); } + push @sfd, '7' => $s7; - # Publication - if ( $host_field = $marc_host->field('260') ) { - my $s = $host_field->as_string('abc'); - if ($s) { - $sfd{d} = $s; - } + # Subfield a - cleaned main entry string + if ($main_entry) { + my $a = $main_entry->as_string; + $a =~ s/\.$// unless $a =~ /\b[a-z]{1,2}\.$/i; + push @sfd, 'a' => $a; } - # Uniform title - if ( $host_field = $marc_host->field('240') ) { - my $s = $host_field->as_string('a'); - if ($s) { - $sfd{s} = $s; - } + # Subfield t - title from 245, cleaned + if ( my $f245 = $marc_host->field('245') ) { + my $f245c = $f245->clone; + $f245c->delete_subfield( code => 'c' ); + my $t = $f245c->as_string; + $t =~ s/(\s*\/\s*|\.)$//; + $t = ucfirst substr( $t, $f245c->indicator('2') ); + push @sfd, 't' => $t; } - # Title - if ( $host_field = $marc_host->field('245') ) { - my $s = $host_field->as_string('ab'); - if ($s) { - $sfd{t} = $s; - } + # Subfield b - edition from 250 + if ( my $f250 = $marc_host->field('250') ) { + my $b = $f250->as_string; + $b =~ s/\.$//; + push @sfd, 'b' => $b; } - # ISSN - if ( $host_field = $marc_host->field('022') ) { - my $s = $host_field->as_string('a'); - if ($s) { - $sfd{x} = $s; - } + # Subfield d - publication info from 260 + if ( my $f260 = $marc_host->field('260') ) { + my $d = $f260->as_string('abc'); + $d =~ s/\.$//; + push @sfd, 'd' => $d; } - # ISBN - if ( $host_field = $marc_host->field('020') ) { - my $s = $host_field->as_string('a'); - if ($s) { - $sfd{z} = $s; - } + # Subfield k - host info from 800-830 fields + for my $f ( $marc_host->field('8[013][01]') ) { + my $k = $f->as_string('abcdnjltnp'); + $k .= ', ISSN ' . $f->subfield('x') if $f->subfield('x'); + $k .= ' ; ' . $f->subfield('v') if $f->subfield('v'); + push @sfd, 'k' => $k; } - if ( C4::Context->preference('UseControlNumber') ) { - # Control number - if ( $host_field = $marc_host->field('001') ) { - $sfd{w} = $host_field->data(); - } + # Subfield x - ISSN from 022 + for my $f ( $marc_host->field('022') ) { + push @sfd, 'x' => $f->subfield('a') if $f->subfield('a'); + } + + # Subfield z - ISBN from 020 + for my $f ( $marc_host->field('020') ) { + push @sfd, 'z' => $f->subfield('a') if $f->subfield('a'); + } - # Control number identifier - if ( $host_field = $marc_host->field('003') ) { - $sfd{w} = '(' . $host_field->data() . ')' . $sfd{w}; + # Subfield w - control number (001 and optionally 003) + if ( C4::Context->preference('UseControlNumber') ) { + if ( my $f001 = $marc_host->field('001') ) { + my $w = $f001->data; + if ( my $f003 = $marc_host->field('003') ) { + $w = '(' . $f003->data . ')' . $w; + } + push @sfd, 'w' => $w; } } - $link_field = MARC::Field->new( 773, '0', ' ', %sfd ); + + # Construct 773 link field + $link_field = MARC::Field->new( 773, '0', ' ', @sfd ); + } elsif ( $marcflavour eq 'UNIMARC' ) { - # Author + # Author (700/710/720) if ( $host_field = $marc_host->field('700') || $marc_host->field('710') || $marc_host->field('720') ) { my $s = $host_field->as_string('ab'); - if ($s) { - $sfd{a} = $s; - } + push @sfd, 'a' => $s if $s; + } + + # Title (200) + if ( $host_field = $marc_host->field('200') ) { + my $s = $host_field->as_string('a'); + push @sfd, 't' => $s if $s; } - # Place of publication + # Place of publication (210$a) if ( $host_field = $marc_host->field('210') ) { my $s = $host_field->as_string('a'); - if ($s) { - $sfd{c} = $s; - } + push @sfd, 'c' => $s if $s; } - # Date of publication + # Date of publication (210$d) if ( $host_field = $marc_host->field('210') ) { my $s = $host_field->as_string('d'); - if ($s) { - $sfd{d} = $s; - } + push @sfd, 'd' => $s if $s; } - # Edition statement + # Edition statement (205) if ( $host_field = $marc_host->field('205') ) { - my $s = $host_field->as_string(); - if ($s) { - $sfd{e} = $s; - } + my $s = $host_field->as_string; + push @sfd, 'e' => $s if $s; } - # Title - if ( $host_field = $marc_host->field('200') ) { - my $s = $host_field->as_string('a'); - if ($s) { - $sfd{t} = $s; - } - } - - #URL + # URL (856$u) if ( $host_field = $marc_host->field('856') ) { my $s = $host_field->as_string('u'); - if ($s) { - $sfd{u} = $s; - } + push @sfd, 'u' => $s if $s; } - # ISSN + # ISSN (011$a) if ( $host_field = $marc_host->field('011') ) { my $s = $host_field->as_string('a'); - if ($s) { - $sfd{x} = $s; - } + push @sfd, 'x' => $s if $s; } - # ISBN + # ISBN (010$a) if ( $host_field = $marc_host->field('010') ) { my $s = $host_field->as_string('a'); - if ($s) { - $sfd{y} = $s; - } + push @sfd, 'y' => $s if $s; } + + # Control number (001) if ( $host_field = $marc_host->field('001') ) { - $sfd{0} = $host_field->data(); + push @sfd, '0' => $host_field->data(); } - $link_field = MARC::Field->new( 461, '0', ' ', %sfd ); + + # Construct 461 link field + $link_field = MARC::Field->new( 461, '0', ' ', @sfd ); } return $link_field; -- 2.49.0