Bug 31925: AutoCreateAuthorities must preserve subject heading thesaurus
When AutoCreateAuthorities creates a new authority for a bib subject
heading that didn't match an existing one, it never set 008 or 040 on the
new MARC::Record, so C4::AuthoritiesMarc::AddAuthority()'s own defaulting
always ran and hardcoded 008/11 to 'a' (LCSH), regardless of the source
heading's real thesaurus. A FAST, MeSH, or other non-LCSH heading (MARC
indicator 2 = 7 with subfield $2, or indicator 2 = 1-6) therefore always
got mis-coded as LCSH on creation. Because the authority was permanently
mis-coded, it could never be found again by thesaurus-aware matching
(LinkerConsiderThesaurus), so every later import of the same non-LCSH
heading created yet another duplicate authority instead of linking to the
one already created (see bug 42694 for a real-world report of this).
This calls Koha::Authority->default_marc21_008($thesaurus) to build the
new authority's 008 - correctly coding position 11 for the source
heading's actual thesaurus - and, for headings identified only by a raw
$2 code, adds a 040$f before calling AddAuthority(), whose existing "only
default if the field isn't already there" guards then leave our
correctly-coded fields alone. No change to AddAuthority() itself is
needed for this. This is MARC21-only (matches the existing marcflavour
branch already in this code path) and ships as an unconditional bug fix,
with no new system preference: it only changes how a *new* authority is
coded going forward and does not touch or merge any existing authority
records.
Test plan (librarian-facing):
1. Turn on the AutoLinkBiblios and AutoCreateAuthorities system
preferences (Administration -> System preferences -> Cataloging).
2. Catalog a new bibliographic record, or edit an existing one, and add a
650 field coded for a non-LCSH thesaurus, e.g.:
650 _7 $a Miracles $2 fast
(2nd indicator = 7, subfield $2 = fast; a FAST heading with no
existing matching authority in your catalogue).
3. Save the record. Koha auto-creates a new "Miracles" authority record,
since none existed yet to link to.
4. In the Authorities module, open the newly created "Miracles" record
for editing and switch to MARC view (Edit -> Edit record, or the "..."
menu -> Edit as new).
5. Click into the 008 field to open its editor plugin.
Before this fix: the "11- Subject heading system/thesaurus" dropdown
is set to "a- Library of Congress Subject Headings", and field 040 has
no $f subfield.
After this fix: that dropdown is now set to "z- Other", and field 040
has a $f subfield containing "fast" — correctly recording the real
source vocabulary instead of silently mis-labelling it as LCSH.
6. As a regression check, repeat steps 2-5 with a plain LCSH heading
instead, e.g.:
650 __0 $a Feminism
(2nd indicator = 0, no $2). Confirm the resulting authority's 008 still
shows "a- Library of Congress Subject Headings" as before — this fix
must not change behaviour for ordinary LCSH headings.
7. Optional, Elasticsearch installations only: with LinkerConsiderThesaurus
also turned on, re-import or re-save a bib with the same FAST heading
from step 2 a second time. It should now link to the authority created
in step 3 instead of creating a second duplicate — this is the actual
duplicate-authority problem reported in bug 42694.
Sponsored-by: Heythrop Library <https://heythroplibrary.co.uk/>
Signed-off-by: Clemens Gresser <cgresser@jesuit.org.uk>
Signed-off-by: Phil Ringnalda <phil@chetcolibrary.org>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
parent
9186341ddd
commit
65dac0fb94
38
C4/Biblio.pm
38
C4/Biblio.pm
|
|
@ -99,6 +99,7 @@ use Koha::Logger;
|
|||
use Koha::Cache::Memory::Lite;
|
||||
use Koha::Caches;
|
||||
use Koha::ClassSources;
|
||||
use Koha::Authority;
|
||||
use Koha::Authority::Types;
|
||||
use Koha::Acquisition::Currencies;
|
||||
use Koha::BackgroundJob::BatchUpdateBiblioHoldsQueue;
|
||||
|
|
@ -811,10 +812,35 @@ sub LinkBibHeadingsToAuthorities {
|
|||
|
||||
if ( C4::Context->preference('marcflavour') eq 'MARC21' ) {
|
||||
my $userenv = C4::Context->userenv;
|
||||
my $library;
|
||||
if ( $userenv && $userenv->{'branch'} ) {
|
||||
$library = Koha::Libraries->find( $userenv->{'branch'} );
|
||||
|
||||
# userenv's library could not exist because of a trick in misc/commit_file.pl
|
||||
# (see FIXME and set_userenv statement there)
|
||||
my $library =
|
||||
$userenv && $userenv->{branch} ? Koha::Libraries->find( $userenv->{branch} ) : undef;
|
||||
my $marcorgcode =
|
||||
$library ? $library->get_effective_marcorgcode : C4::Context->preference('MARCOrgCode');
|
||||
|
||||
# Bug 31925: code the new authority with the source heading's actual
|
||||
# thesaurus instead of relying on AddAuthority()'s LCSH-only default.
|
||||
# AddAuthority() only defaults 008/040 when they aren't already present
|
||||
# on the record, so pre-populating them here is sufficient - no change
|
||||
# to AddAuthority() itself is needed.
|
||||
if ( $heading->{thesaurus} ) {
|
||||
my $date = POSIX::strftime( '%y%m%d', localtime );
|
||||
$marcrecordauth->insert_fields_ordered(
|
||||
MARC::Field->new(
|
||||
'008', $date . Koha::Authority->default_marc21_008( $heading->{thesaurus} )
|
||||
)
|
||||
);
|
||||
|
||||
my @f040_subfields = ( 'a' => $marcorgcode, 'c' => $marcorgcode );
|
||||
push @f040_subfields, ( 'f' => $heading->{thesaurus} )
|
||||
unless exists
|
||||
$Koha::Authority::MARC21_THESAURUS_TO_CONTROL_FIELD_008_11->{ $heading->{thesaurus} };
|
||||
$marcrecordauth->insert_fields_ordered(
|
||||
MARC::Field->new( '040', '', '', @f040_subfields ) );
|
||||
}
|
||||
|
||||
$marcrecordauth->insert_fields_ordered(
|
||||
MARC::Field->new(
|
||||
'667', '', '',
|
||||
|
|
@ -825,10 +851,8 @@ sub LinkBibHeadingsToAuthorities {
|
|||
$cite =~ s/^[\s\,]*//;
|
||||
$cite =~ s/[\s\,]*$//;
|
||||
$cite =
|
||||
C4::Context->preference('GenerateAuthorityField670') . ": ("
|
||||
. (
|
||||
$library ? $library->get_effective_marcorgcode : C4::Context->preference('MARCOrgCode') )
|
||||
. ")"
|
||||
C4::Context->preference('GenerateAuthorityField670') . ": ("
|
||||
. "$marcorgcode)"
|
||||
. $bib->subfield( '999', 'c' ) . ": "
|
||||
. $cite;
|
||||
$marcrecordauth->insert_fields_ordered( MARC::Field->new( '670', '', '', 'a' => $cite ) );
|
||||
|
|
|
|||
|
|
@ -1114,6 +1114,65 @@ subtest "LinkBibHeadingsToAuthorities record generation tests" => sub {
|
|||
);
|
||||
};
|
||||
|
||||
subtest "LinkBibHeadingsToAuthorities codes new authorities with the source thesaurus (bug 31925)" => sub {
|
||||
plan tests => 7;
|
||||
|
||||
my $biblio_mod = Test::MockModule->new('C4::Linker::Default');
|
||||
$biblio_mod->mock(
|
||||
'get_link',
|
||||
sub {
|
||||
return ( undef, undef, 0 );
|
||||
}
|
||||
);
|
||||
|
||||
t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' );
|
||||
t::lib::Mocks::mock_preference( 'AutoCreateAuthorities', '1' );
|
||||
|
||||
my $linker = C4::Linker::Default->new();
|
||||
|
||||
# Case 1: plain LCSH (ind2=0, no $2) - regression guard, must stay coded 'a'
|
||||
my $biblio = $builder->build_sample_biblio();
|
||||
my $record = $biblio->metadata->record;
|
||||
my $field = MARC::Field->new( '650', '', '0', 'a' => 'Feminism' );
|
||||
$record->append_fields($field);
|
||||
LinkBibHeadingsToAuthorities( $linker, $record, "", undef, 650 );
|
||||
my $authority = GetAuthority( $record->subfield( '650', '9' ) );
|
||||
is( substr( $authority->field('008')->data(), 11, 1 ), 'a', 'Plain LCSH heading (ind2=0) is coded 008/11=a' );
|
||||
is( $authority->subfield( '040', 'f' ), undef, 'Plain LCSH heading (ind2=0) gets no 040$f' );
|
||||
|
||||
# Case 2: FAST heading (ind2=7, $2=fast) - the actual bug: must NOT be coded as LCSH
|
||||
$biblio = $builder->build_sample_biblio();
|
||||
$record = $biblio->metadata->record;
|
||||
$field = MARC::Field->new( '650', '', '7', 'a' => 'Miracles', '2' => 'fast' );
|
||||
$record->append_fields($field);
|
||||
LinkBibHeadingsToAuthorities( $linker, $record, "", undef, 650 );
|
||||
$authority = GetAuthority( $record->subfield( '650', '9' ) );
|
||||
is( substr( $authority->field('008')->data(), 11, 1 ), 'z', 'FAST heading (ind2=7, $2=fast) is coded 008/11=z' );
|
||||
is( $authority->subfield( '040', 'f' ), 'fast', 'FAST heading (ind2=7, $2=fast) gets 040$f=fast' );
|
||||
|
||||
# Case 3: MeSH heading (ind2=2, no $2)
|
||||
$biblio = $builder->build_sample_biblio();
|
||||
$record = $biblio->metadata->record;
|
||||
$field = MARC::Field->new( '650', '', '2', 'a' => 'Something' );
|
||||
$record->append_fields($field);
|
||||
LinkBibHeadingsToAuthorities( $linker, $record, "", undef, 650 );
|
||||
$authority = GetAuthority( $record->subfield( '650', '9' ) );
|
||||
is( substr( $authority->field('008')->data(), 11, 1 ), 'c', 'MeSH heading (ind2=2) is coded 008/11=c' );
|
||||
is( $authority->subfield( '040', 'f' ), undef, 'MeSH heading (ind2=2) gets no 040$f' );
|
||||
|
||||
# Case 4: non-subject heading (personal name added entry) is unaffected - no thesaurus semantics
|
||||
$biblio = $builder->build_sample_biblio();
|
||||
$record = $biblio->metadata->record;
|
||||
$field = MARC::Field->new( '700', '', '', 'a' => 'Doe, Jane' );
|
||||
$record->append_fields($field);
|
||||
LinkBibHeadingsToAuthorities( $linker, $record, "", undef, 700 );
|
||||
$authority = GetAuthority( $record->subfield( '700', '9' ) );
|
||||
is(
|
||||
substr( $authority->field('008')->data(), 11, 1 ), 'a',
|
||||
'Non-subject heading (700) keeps the default LCSH 008/11=a coding, unaffected by this fix'
|
||||
);
|
||||
};
|
||||
|
||||
subtest 'autoControlNumber tests' => sub {
|
||||
|
||||
plan tests => 3;
|
||||
|
|
|
|||
Loading…
Reference in New Issue