Bug 31925: Add thesaurus/008 lookup and default MARC21 008 builder to Koha::Authority
AutoCreateAuthorities builds a brand-new authority record whenever a bib
subject heading (6XX) has no match, but always lets the record fall back
to C4::AuthoritiesMarc::AddAuthority()'s default 008/040, which hardcodes
008 position 11 ("Subject heading system/thesaurus") to 'a' (LCSH) no
matter what thesaurus the source heading actually uses. This is the first
step towards fixing that.
Adds two things to Koha::Authority:
- $MARC21_THESAURUS_TO_CONTROL_FIELD_008_11: a single-source-of-truth
lookup mapping a thesaurus name (as already derived by C4::Heading from
MARC indicator 2 / subfield $2, e.g. 'lcsh', 'mesh', or a raw $2 code
such as 'fast') to its MARC21 authority 008/11 code, per the LOC ad008
code list. This table previously only existed once, for a different
purpose, in Koha::SearchEngine::Elasticsearch::QueryBuilder (used for
building thesaurus search queries) - it's promoted here so both that
and the authority-creation fix that follows can read from one place
instead of two copies that can silently drift apart.
- default_marc21_008($thesaurus): builds the default 34-character body of
a new MARC21 authority's 008 field, honouring the
MARCAuthorityControlField008 system preference. When $thesaurus is
given, position 11 is set from the table above instead of whatever the
default/syspref value carries, falling back to 'z' (Other) for a
thesaurus with no dedicated code.
AddAuthority() is refactored to build its own (thesaurus-less, LCSH
default) 008 via this new method too, replacing its previous inline copy
of the same defaulting logic - pure refactor, no behaviour change.
Nothing thesaurus-aware calls it yet.
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
9eaeae69e5
commit
4bfb9abc68
|
|
@ -620,16 +620,7 @@ sub AddAuthority {
|
|||
}
|
||||
my $date = POSIX::strftime( "%y%m%d", localtime );
|
||||
if ( !$record->field('008') ) {
|
||||
|
||||
# Get a valid default value for field 008
|
||||
my $default_008 = C4::Context->preference('MARCAuthorityControlField008');
|
||||
if ( !$default_008 or length($default_008) < 34 ) {
|
||||
$default_008 = '|| aca||aabn | a|a d';
|
||||
} else {
|
||||
$default_008 = substr( $default_008, 0, 34 );
|
||||
}
|
||||
|
||||
$record->insert_fields_ordered( MARC::Field->new( '008', $date . $default_008 ) );
|
||||
$record->insert_fields_ordered( MARC::Field->new( '008', $date . Koha::Authority->default_marc21_008 ) );
|
||||
}
|
||||
if ( !$record->field('040') ) {
|
||||
$record->insert_fields_ordered(
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ use Modern::Perl;
|
|||
|
||||
use Scalar::Util qw( blessed );
|
||||
|
||||
use C4::Context;
|
||||
|
||||
use base qw(Koha::Object);
|
||||
|
||||
use Koha::Authority::ControlledIndicators;
|
||||
|
|
@ -292,6 +294,77 @@ sub record_schema {
|
|||
: 'MARC21';
|
||||
}
|
||||
|
||||
=head3 $MARC21_THESAURUS_TO_CONTROL_FIELD_008_11
|
||||
|
||||
my $code = $Koha::Authority::MARC21_THESAURUS_TO_CONTROL_FIELD_008_11->{$thesaurus};
|
||||
|
||||
The mapping of a subject heading's thesaurus name (as derived by
|
||||
C4::Heading from MARC indicator 2 / subfield $2, e.g. 'lcsh', 'mesh', or a
|
||||
raw $2 code such as 'fast') to its MARC21 authority 008/11 code ("Subject
|
||||
heading system/thesaurus"), per
|
||||
L<https://www.loc.gov/marc/authority/ad008.html>.
|
||||
|
||||
Note that C<sears> and C<aat> map to 008/11 values here but never appear
|
||||
as a thesaurus name derived by C4::Heading, because they don't have their
|
||||
own MARC21 indicator 2 value (see the LOC list linked above).
|
||||
|
||||
=cut
|
||||
|
||||
our $MARC21_THESAURUS_TO_CONTROL_FIELD_008_11 = {
|
||||
lcsh => 'a',
|
||||
lcac => 'b',
|
||||
mesh => 'c',
|
||||
nal => 'd',
|
||||
notapplicable => 'n',
|
||||
cash => 'k',
|
||||
rvm => 'v',
|
||||
aat => 'r',
|
||||
sears => 's',
|
||||
notdefined => 'z',
|
||||
notspecified => '|',
|
||||
};
|
||||
|
||||
=head3 default_marc21_008
|
||||
|
||||
my $default_008 = Koha::Authority->default_marc21_008;
|
||||
my $default_008 = Koha::Authority->default_marc21_008($thesaurus);
|
||||
|
||||
Returns the default 34-character body (i.e. everything after the
|
||||
6-character date) to use for a new MARC21 authority record's 008 field,
|
||||
honouring the I<MARCAuthorityControlField008> system preference and
|
||||
falling back to Koha's hardcoded default when it isn't set to a valid (at
|
||||
least 34 character) value.
|
||||
|
||||
If C<$thesaurus> is passed, position 11 ("Subject heading
|
||||
system/thesaurus") is set from
|
||||
L<$MARC21_THESAURUS_TO_CONTROL_FIELD_008_11> instead of whatever the
|
||||
default/syspref value carries, falling back to 'z' (Other) for a
|
||||
thesaurus with no dedicated code -- consistent with how Elasticsearch
|
||||
indexing already reconciles 008/11 vs 040$f (see
|
||||
Koha::SearchEngine::Elasticsearch::_process_mappings, where a 'z' is
|
||||
dropped in favour of a genuine 040$f value).
|
||||
|
||||
=cut
|
||||
|
||||
sub default_marc21_008 {
|
||||
my ( $class, $thesaurus ) = @_;
|
||||
|
||||
my $default_008 = C4::Context->preference('MARCAuthorityControlField008');
|
||||
if ( !$default_008 or length($default_008) < 34 ) {
|
||||
$default_008 = '|| aca||aabn | a|a d';
|
||||
} else {
|
||||
$default_008 = substr( $default_008, 0, 34 );
|
||||
}
|
||||
|
||||
if ( defined $thesaurus ) {
|
||||
|
||||
# Position 11 is absolute (over date + body); within the 34-char body alone that's index 11 - 6 = 5.
|
||||
substr( $default_008, 5, 1, $MARC21_THESAURUS_TO_CONTROL_FIELD_008_11->{$thesaurus} // 'z' );
|
||||
}
|
||||
|
||||
return $default_008;
|
||||
}
|
||||
|
||||
=head3 to_api_mapping
|
||||
|
||||
This method returns the mapping for representing a Koha::Authority object
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
use Modern::Perl;
|
||||
|
||||
use Test::MockModule;
|
||||
use Test::More tests => 2;
|
||||
use Test::More tests => 3;
|
||||
use Test::NoWarnings;
|
||||
|
||||
use C4::AuthoritiesMarc;
|
||||
|
|
@ -116,3 +116,41 @@ subtest 'move_to_deleted' => sub {
|
|||
|
||||
$schema->storage->txn_rollback;
|
||||
};
|
||||
|
||||
subtest 'default_marc21_008 tests (bug 31925)' => sub {
|
||||
plan tests => 7;
|
||||
|
||||
is(
|
||||
substr( Koha::Authority->default_marc21_008('lcsh'), 5, 1 ), 'a',
|
||||
'lcsh maps to 008/11 code a'
|
||||
);
|
||||
is(
|
||||
substr( Koha::Authority->default_marc21_008('mesh'), 5, 1 ), 'c',
|
||||
'mesh maps to 008/11 code c'
|
||||
);
|
||||
is(
|
||||
substr( Koha::Authority->default_marc21_008('rvm'), 5, 1 ), 'v',
|
||||
'rvm maps to 008/11 code v'
|
||||
);
|
||||
is(
|
||||
substr( Koha::Authority->default_marc21_008('fast'), 5, 1 ), 'z',
|
||||
'Unrecognized raw $2 code (e.g. fast, from an ind2=7 heading) maps to 008/11 code z (Other)'
|
||||
);
|
||||
|
||||
t::lib::Mocks::mock_preference( 'MARCAuthorityControlField008', '' );
|
||||
is(
|
||||
Koha::Authority->default_marc21_008, '|| aca||aabn | a|a d',
|
||||
'Falls back to the hardcoded default when the syspref is unset, and thesaurus is not passed'
|
||||
);
|
||||
is(
|
||||
substr( Koha::Authority->default_marc21_008('fast'), 5, 1 ), 'z',
|
||||
'Thesaurus code is still applied on top of the hardcoded default'
|
||||
);
|
||||
|
||||
my $custom = '||caaa||aabn | a|a d##padding';
|
||||
t::lib::Mocks::mock_preference( 'MARCAuthorityControlField008', $custom );
|
||||
is(
|
||||
Koha::Authority->default_marc21_008, substr( $custom, 0, 34 ),
|
||||
'Uses the syspref value, truncated to 34 characters, when valid'
|
||||
);
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue