Bug 28445: Split and join on ' | ' instead of '|' for repeatable
[koha.git] / Koha / Item / Attributes.pm
1 package Koha::Item::Attributes;
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18 use Modern::Perl;
19 use MARC::Record;
20 use MARC::Field;
21 use List::MoreUtils qw( uniq );
22
23 use C4::Biblio;
24 use C4::Charset qw( StripNonXmlChars );
25
26 =head1 NAME
27
28 Koha::Item::Attributes - Class to represent the additional attributes of items.
29
30 Additional attributes are 'more subfields xml'
31
32 =head1 API
33
34 =head2 Class methods
35
36 =cut
37
38 =head3 new_from_marcxml
39
40     my $attributes = Koha::Item::Attributes->new_from_marcxml( $item->more_subfield_xml );
41
42 Constructor that takes a MARCXML.
43
44 =cut
45
46 # FIXME maybe this needs to care about repeatable but don't from batchMod - To implement later?
47 sub new_from_marcxml {
48     my ( $class, $more_subfields_xml ) = @_;
49
50     my $self = {};
51     if ($more_subfields_xml) {
52         # FIXME MARC::Record->new_from_xml (vs MARC::Record::new_from_xml) does not return the correctly encoded subfield code (??)
53         my $marc_more =
54           MARC::Record::new_from_xml(
55             C4::Charset::StripNonXmlChars($more_subfields_xml), 'UTF-8' );
56
57         # use of tag 999 is arbitrary, and doesn't need to match the item tag
58         # used in the framework
59         my $field = $marc_more->field('999');
60         my $more_subfields = [ uniq map { $_->[0] } $field->subfields ];
61         for my $more_subfield (@$more_subfields) {
62             my @s = $field->subfield($more_subfield);
63             $self->{$more_subfield} = join ' | ', @s;
64         }
65     }
66     return bless $self, $class;
67 }
68
69 =head3 new
70
71 Constructor
72
73 =cut
74
75 # FIXME maybe this needs to care about repeatable but don't from batchMod - To implement later?
76 sub new {
77     my ( $class, $attributes ) = @_;
78
79     my $self = $attributes;
80     return bless $self, $class;
81 }
82
83 =head3 to_marcxml
84
85     $attributes->to_marcxml;
86
87     $item->more_subfields_xml( $attributes->to_marcxml );
88
89 Return the MARCXML representation of the attributes.
90
91 =cut
92
93 sub to_marcxml {
94     my ( $self, $frameworkcode ) = @_;
95
96     return unless keys %$self;
97
98     my $tagslib =
99       C4::Biblio::GetMarcStructure( 1, $frameworkcode, { unsafe => 1 } );
100
101     my ( $itemtag, $itemtagsubfield ) =
102       C4::Biblio::GetMarcFromKohaField("items.itemnumber");
103     my @subfields;
104     for my $tagsubfield (
105         sort {
106             $tagslib->{$itemtag}->{$a}->{display_order} <=> $tagslib->{$itemtag}->{$b}->{display_order}
107               || $tagslib->{$itemtag}->{$a}->{subfield} cmp $tagslib->{$itemtag}->{$b}->{subfield}
108         } keys %$self
109       )
110     {
111         next
112           if not defined $self->{$tagsubfield}
113           or $self->{$tagsubfield} eq "";
114
115         if ( $tagslib->{$itemtag}->{$tagsubfield}->{repeatable} ) {
116             my @values = split ' \| ', $self->{$tagsubfield};
117             push @subfields, ( $tagsubfield => $_ ) for @values;
118         }
119         else {
120             push @subfields, ( $tagsubfield => $self->{$tagsubfield} );
121         }
122     }
123
124     return unless @subfields;
125
126     my $marc_more = MARC::Record->new();
127
128     # use of tag 999 is arbitrary, and doesn't need to match the item tag
129     # used in the framework
130     $marc_more->append_fields(
131         MARC::Field->new( '999', ' ', ' ', @subfields ) );
132     $marc_more->encoding("UTF-8");
133     return $marc_more->as_xml("USMARC");
134 }
135
136 =head3 to_hashref
137
138     $attributes->to_hashref;
139
140 Returns the hashref representation of the attributes.
141
142 =cut
143
144 sub to_hashref {
145     my ($self) = @_;
146     return { map { $_ => $self->{$_} } keys %$self };
147 }
148
149 1;