Bug 30848: Add an ExpandCodedFields RecordProcessor filter
This patch introduces a RecordProcessor filter for MARC::Record objects
that replaces Koha codes with descriptions in the MARC::Record passed to the processor.
Target usage:
my $biblio = Koha::Biblios->find(
$biblio_id,
{ prefetch => [ metadata ] }
);
my $record = $biblio->metadata->record;
my $processor = Koha::RecordProcessor->new(
{
filters => ('ExpandCodedFields'),
options => {
interface => 'opac',
frameworkcode => $biblio->frameworkcode
}
}
);
$processor->process( $record );
Test plan
* Read the included unit test and confirm it makes sense and passes
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
(cherry picked from commit 62bba6d9e1)
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 0a86104294)
Signed-off-by: Arthur Suzuki <arthur.suzuki@biblibre.com>
(cherry picked from commit 52dd29792e)
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
This commit is contained in:
parent
1d4dbdab06
commit
26e2f2c11a
|
|
@ -0,0 +1,140 @@
|
|||
package Koha::Filter::MARC::ExpandCodedFields;
|
||||
|
||||
# Copyright 2022 PTFS Europe
|
||||
#
|
||||
# This file is part of Koha.
|
||||
#
|
||||
# Koha is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Koha is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Koha; if not, see <http://www.gnu.org/licenses>.
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Koha::Filter::MARC::ExpandCodedFields - Replaces AV codes with descriptions in MARC::Record objects.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $biblio = Koha::Biblios->find(
|
||||
$biblio_id,
|
||||
{ prefetch => [ metadata ] }
|
||||
);
|
||||
|
||||
my $record = $biblio->metadata->record;
|
||||
|
||||
my $record_processor = Koha::RecordProcessor->new(
|
||||
{
|
||||
filters => ['ExpandCodedFields'],
|
||||
options => {
|
||||
interface => 'opac',
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$record_processor->process($record);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Filter to replace Koha AV codes in MARC::Records with their Koha AV descriptions.
|
||||
|
||||
=cut
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use C4::Biblio qw( GetAuthorisedValueDesc );
|
||||
|
||||
use Koha::Caches;
|
||||
|
||||
use base qw(Koha::RecordProcessor::Base);
|
||||
our $NAME = 'ExpandCodedFields';
|
||||
|
||||
=head2 filter
|
||||
|
||||
Embed items into the MARC::Record object.
|
||||
|
||||
=cut
|
||||
|
||||
sub filter {
|
||||
my $self = shift;
|
||||
my $record = shift;
|
||||
|
||||
return unless defined $record and ref($record) eq 'MARC::Record';
|
||||
|
||||
my $params = $self->params;
|
||||
my $interface = $params->{options}->{interface} // 'opac';
|
||||
my $opac = $interface eq 'opac' ? 1 : 0;
|
||||
my $frameworkcode = $params->{options}->{frameworkcode} // q{};
|
||||
|
||||
my $marcflavour = C4::Context->preference('marcflavour');
|
||||
my $coded_fields = _getCodedFields($frameworkcode);
|
||||
for my $tag ( keys %$coded_fields ) {
|
||||
for my $field ( $record->field($tag) ) {
|
||||
my @new_subfields = ();
|
||||
for my $subfield ( $field->subfields() ) {
|
||||
my ( $letter, $value ) = @$subfield;
|
||||
|
||||
# Replace the field value with the authorised value
|
||||
# *except* for MARC21 field 942$n (suppression in opac)
|
||||
if ( !( $tag eq '942' && $subfield->[0] eq 'n' )
|
||||
|| $marcflavour eq 'UNIMARC' )
|
||||
{
|
||||
$value =
|
||||
GetAuthorisedValueDesc( $tag, $letter, $value, '',
|
||||
$coded_fields, undef, $opac )
|
||||
if $coded_fields->{$tag}->{$letter};
|
||||
}
|
||||
push( @new_subfields, $letter, $value );
|
||||
}
|
||||
$field->replace_with(
|
||||
MARC::Field->new(
|
||||
$tag, $field->indicator(1),
|
||||
$field->indicator(2), @new_subfields
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
sub _getCodedFields {
|
||||
my ($frameworkcode) = @_;
|
||||
$frameworkcode //= "";
|
||||
|
||||
my $cache = Koha::Caches->get_instance();
|
||||
my $cache_key = "MarcCodedFields-$frameworkcode";
|
||||
my $cached = $cache->get_from_cache( $cache_key, { unsafe => 1 } );
|
||||
return $cached if $cached;
|
||||
|
||||
my $coded_fields = {
|
||||
map {
|
||||
$_->tagfield => {
|
||||
$_->tagsubfield => {
|
||||
'authorised_value' => $_->authorised_value
|
||||
}
|
||||
}
|
||||
} Koha::MarcSubfieldStructures->search(
|
||||
{
|
||||
frameworkcode => $frameworkcode,
|
||||
authorised_value => { '>' => '' }
|
||||
},
|
||||
{
|
||||
columns => [ 'tagfield', 'tagsubfield', 'authorised_value' ],
|
||||
order_by => [ 'tagfield', 'tagsubfield' ]
|
||||
}
|
||||
)->as_list
|
||||
};
|
||||
|
||||
$cache->set_in_cache( $cache_key, $coded_fields );
|
||||
return $coded_fields;
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -81,6 +81,7 @@ if ( $op eq 'add_form' ) {
|
|||
$cache->clear_from_cache("MarcStructure-1-$frameworkcode");
|
||||
$cache->clear_from_cache("default_value_for_mod_marc-");
|
||||
$cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
|
||||
$cache->clear_from_cache("MarcCodedFields-$frameworkcode");
|
||||
$op = 'list';
|
||||
} elsif ( $op eq 'delete_confirm' ) {
|
||||
my $framework = Koha::BiblioFrameworks->find($frameworkcode);
|
||||
|
|
@ -112,6 +113,7 @@ if ( $op eq 'add_form' ) {
|
|||
$cache->clear_from_cache("MarcStructure-1-$frameworkcode");
|
||||
$cache->clear_from_cache("default_value_for_mod_marc-");
|
||||
$cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
|
||||
$cache->clear_from_cache("MarcCodedFields-$frameworkcode");
|
||||
$op = 'list';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -310,6 +310,7 @@ elsif ( $op eq 'add_validate' ) {
|
|||
$cache->clear_from_cache("MarcStructure-1-$frameworkcode");
|
||||
$cache->clear_from_cache("default_value_for_mod_marc-");
|
||||
$cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
|
||||
$cache->clear_from_cache("MarcCodedFields-$frameworkcode");
|
||||
|
||||
print $input->redirect("/cgi-bin/koha/admin/marc_subfields_structure.pl?tagfield=$tagfield&frameworkcode=$frameworkcode");
|
||||
exit;
|
||||
|
|
@ -348,6 +349,7 @@ elsif ( $op eq 'delete_confirmed' ) {
|
|||
$cache->clear_from_cache("MarcStructure-1-$frameworkcode");
|
||||
$cache->clear_from_cache("default_value_for_mod_marc-");
|
||||
$cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
|
||||
$cache->clear_from_cache("MarcCodedFields-$frameworkcode");
|
||||
print $input->redirect("/cgi-bin/koha/admin/marc_subfields_structure.pl?tagfield=$tagfield&frameworkcode=$frameworkcode");
|
||||
exit;
|
||||
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ if ($op eq 'add_form') {
|
|||
$cache->clear_from_cache("MarcStructure-1-$frameworkcode");
|
||||
$cache->clear_from_cache("default_value_for_mod_marc-");
|
||||
$cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
|
||||
$cache->clear_from_cache("MarcCodedFields-$frameworkcode");
|
||||
print $input->redirect("/cgi-bin/koha/admin/marctagstructure.pl?searchfield=$tagfield&frameworkcode=$frameworkcode");
|
||||
exit;
|
||||
# END $OP eq ADD_VALIDATE
|
||||
|
|
@ -182,6 +183,7 @@ if ($op eq 'add_form') {
|
|||
$cache->clear_from_cache("MarcStructure-1-$frameworkcode");
|
||||
$cache->clear_from_cache("default_value_for_mod_marc-");
|
||||
$cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
|
||||
$cache->clear_from_cache("MarcCodedFields-$frameworkcode");
|
||||
$template->param( searchfield => $searchfield );
|
||||
# END $OP eq DELETE_CONFIRMED
|
||||
################## ITEMTYPE_CREATE ##################################
|
||||
|
|
|
|||
|
|
@ -0,0 +1,97 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# This file is part of Koha.
|
||||
#
|
||||
# Koha is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Koha is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Koha; if not, see <http://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use Test::More tests => 1;
|
||||
|
||||
use t::lib::TestBuilder;
|
||||
|
||||
use C4::Biblio qw( GetMarcSubfieldStructure );
|
||||
|
||||
use Koha::Database;
|
||||
|
||||
use Koha::AuthorisedValueCategory;
|
||||
use Koha::Caches;
|
||||
|
||||
use Koha::RecordProcessor;
|
||||
|
||||
my $schema = Koha::Database->schema();
|
||||
my $builder = t::lib::TestBuilder->new();
|
||||
|
||||
subtest 'ExpandCodedFields tests' => sub {
|
||||
|
||||
plan tests => 10;
|
||||
|
||||
$schema->storage->txn_begin();
|
||||
|
||||
# Add a biblio
|
||||
my $biblio = $builder->build_sample_biblio;
|
||||
my $record = $biblio->metadata->record;
|
||||
$record->field('942')->update( n => 1 );
|
||||
$record->append_fields(
|
||||
MARC::Field->new( '590', '', '', a => 'CODE' ),
|
||||
);
|
||||
|
||||
Koha::AuthorisedValueCategory->new({ category_name => 'TEST' })->store;
|
||||
Koha::AuthorisedValue->new(
|
||||
{
|
||||
category => 'TEST',
|
||||
authorised_value => 'CODE',
|
||||
lib => 'Description should show',
|
||||
lib_opac => 'Description should show OPAC'
|
||||
}
|
||||
)->store;
|
||||
my $mss = Koha::MarcSubfieldStructures->find({tagfield => "590", tagsubfield => "a", frameworkcode => $biblio->frameworkcode });
|
||||
$mss->update({ authorised_value => "TEST" });
|
||||
|
||||
my $cache = Koha::Caches->get_instance;
|
||||
$cache->clear_from_cache("MarcCodedFields-");
|
||||
|
||||
C4::Biblio::ModBiblio( $record, $biblio->biblionumber );
|
||||
$biblio = Koha::Biblios->find( $biblio->biblionumber);
|
||||
$record = $biblio->metadata->record;
|
||||
|
||||
is( $record->field('590')->subfield('a'), 'CODE', 'Record prior to filtering contains AV Code' );
|
||||
is( $record->field('942')->subfield('n'), 1, 'Record suppression is numeric prior to filtering' );
|
||||
|
||||
my $processor = Koha::RecordProcessor->new(
|
||||
{
|
||||
schema => 'MARC',
|
||||
filters => ['ExpandCodedFields'],
|
||||
}
|
||||
);
|
||||
is( ref($processor), 'Koha::RecordProcessor', 'Created record processor with ExpandCodedFields filter' );
|
||||
|
||||
my $result = $processor->process( $record );
|
||||
is( ref($result), 'MARC::Record', 'It returns a reference to a MARC::Record object' );
|
||||
is( $result->field('590')->subfield('a'), 'Description should show OPAC', 'Returned record contains AV OPAC description (interface defaults to opac)' );
|
||||
is( $record->field('590')->subfield('a'), 'Description should show OPAC', 'Original record now contains AV OPAC description (interface defaults to opac)' );
|
||||
is( $record->field('942')->subfield('n'), 1, 'Record suppression is still numeric after filtering' );
|
||||
|
||||
# reset record for next test
|
||||
$record = $biblio->metadata->record;
|
||||
is( $record->field('590')->subfield('a'), 'CODE', 'Record reset contains AV Code' );
|
||||
|
||||
# set interface
|
||||
$processor->options({ interface => 'intranet' });
|
||||
$result = $processor->process( $record );
|
||||
is( $record->field('590')->subfield('a'), 'Description should show', 'Original record now contains AV description (interface set to intranet)' );
|
||||
is( $record->field('942')->subfield('n'), 1, 'Item suppression field remains numeric after filtering' );
|
||||
|
||||
$schema->storage->txn_rollback();
|
||||
};
|
||||
Loading…
Reference in New Issue