Bug 33749: Add TrimFields field class
[koha.git] / Koha / Filter / MARC / ExpandCodedFields.pm
1 package Koha::Filter::MARC::ExpandCodedFields;
2
3 # Copyright 2022 PTFS Europe
4 #
5 # This file is part of Koha.
6 #
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20 =head1 NAME
21
22 Koha::Filter::MARC::ExpandCodedFields - Replaces AV codes with descriptions in MARC::Record objects.
23
24 =head1 SYNOPSIS
25
26   my $biblio = Koha::Biblios->find(
27       $biblio_id,
28       { prefetch => [ metadata ] }
29   );
30
31   my $record = $biblio->metadata->record;
32
33   my $record_processor = Koha::RecordProcessor->new(
34     {
35         filters => ['ExpandCodedFields'],
36         options => {
37             interface => 'opac',
38         }
39     }
40   );
41
42   $record_processor->process($record);
43
44 =head1 DESCRIPTION
45
46 Filter to replace Koha AV codes in MARC::Records with their Koha AV descriptions.
47
48 =cut
49
50 use Modern::Perl;
51
52 use C4::Biblio qw( GetAuthorisedValueDesc );
53
54 use Koha::Caches;
55
56 use base qw(Koha::RecordProcessor::Base);
57 our $NAME = 'ExpandCodedFields';
58
59 =head2 filter
60
61 Embed items into the MARC::Record object.
62
63 =cut
64
65 sub filter {
66     my $self   = shift;
67     my $record = shift;
68
69     return unless defined $record and ref($record) eq 'MARC::Record';
70
71     my $params        = $self->params;
72     my $interface     = $params->{options}->{interface} // 'opac';
73     my $opac          = $interface eq 'opac' ? 1 : 0;
74     my $frameworkcode = $params->{options}->{frameworkcode} // q{};
75
76     my $marcflavour  = C4::Context->preference('marcflavour');
77     my $coded_fields = _getCodedFields($frameworkcode);
78     for my $tag ( keys %$coded_fields ) {
79         for my $field ( $record->field($tag) ) {
80             my @new_subfields = ();
81             for my $subfield ( $field->subfields() ) {
82                 my ( $letter, $value ) = @$subfield;
83
84                 # Replace the field value with the authorised value
85                 # *except* for MARC21 field 942$n (suppression in opac)
86                 if ( !( $tag eq '942' && $subfield->[0] eq 'n' )
87                     || $marcflavour eq 'UNIMARC' )
88                 {
89                     $value =
90                       GetAuthorisedValueDesc( $tag, $letter, $value, '',
91                         $coded_fields, undef, $opac )
92                       if $coded_fields->{$tag}->{$letter};
93                 }
94                 push( @new_subfields, $letter, $value );
95             }
96             $field->replace_with(
97                 MARC::Field->new(
98                     $tag,                 $field->indicator(1),
99                     $field->indicator(2), @new_subfields
100                 )
101             );
102         }
103     }
104
105     return $record;
106 }
107
108 sub _getCodedFields {
109     my ($frameworkcode) = @_;
110     $frameworkcode //= "";
111
112     my $cache     = Koha::Caches->get_instance();
113     my $cache_key = "MarcCodedFields-$frameworkcode";
114     my $cached    = $cache->get_from_cache( $cache_key, { unsafe => 1 } );
115     return $cached if $cached;
116
117     my $coded_fields = {};
118     my @fields = Koha::MarcSubfieldStructures->search(
119             {
120                 frameworkcode    => $frameworkcode,
121                 authorised_value => { '>' => '' }
122             },
123             {
124                 columns  => [ 'tagfield', 'tagsubfield', 'authorised_value' ],
125                 order_by => [ 'tagfield', 'tagsubfield' ]
126             }
127         )->as_list;
128     for my $field (@fields) {
129         $coded_fields->{ $field->tagfield }->{ $field->tagsubfield }->{'authorised_value'} = $field->authorised_value;
130     }
131
132     $cache->set_in_cache( $cache_key, $coded_fields );
133     return $coded_fields;
134 }
135
136 1;