1 package C4::Heading::MARC21;
3 # Copyright (C) 2008 LibLime
5 # This file is part of Koha.
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.
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.
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>.
31 use C4::Heading::MARC21;
35 This is an internal helper class used by
36 C<C4::Heading> to parse headings data from
37 MARC21 records. Object of this type
38 do not carry data, instead, they only
41 =head1 DATA STRUCTURES
43 FIXME - this should be moved to a configuration file.
45 =head2 bib_heading_fields
49 my $bib_heading_fields = {
51 auth_type => 'PERSO_NAME',
52 subfields => 'abcdfghjklmnopqrst',
56 auth_type => 'CORPO_NAME',
57 subfields => 'abcdfghklmnoprst',
61 auth_type => 'MEETI_NAME',
62 subfields => 'acdefghklnpqst',
66 auth_type => 'UNIF_TITLE',
67 subfields => 'adfghklmnoprst',
71 auth_type => 'NAME_EVENT',
72 subfields => 'acdgvxyz68',
76 auth_type => 'CHRON_TERM',
77 subfields => 'abvxyz68',
81 auth_type => 'TOPIC_TERM',
82 subfields => 'abvxyz68',
86 auth_type => 'GEOGR_NAME',
87 subfields => 'avxyz68',
91 auth_type => 'GENRE/FORM',
92 subfields => 'abvxyz68',
96 auth_type => 'MED_PERFRM',
101 auth_type => 'TOPIC_TERM',
102 subfields => 'vxyz68'
105 auth_type => 'GEOGR_NAME',
106 subfields => 'vxyz68'
109 auth_type => 'CHRON_TERM',
110 subfields => 'vxyz68'
113 auth_type => 'GENRE/FORM',
114 subfields => 'vxyz68'
116 '440' => { auth_type => 'UNIF_TITLE', subfields => 'anp', series => 1 },
118 auth_type => 'PERSO_NAME',
119 subfields => 'abcdfghjklmnopqrstvxyz',
123 auth_type => 'CORPO_NAME',
124 subfields => 'abcdfghklmnoprstvxyz',
128 auth_type => 'MEETI_NAME',
129 subfields => 'acdefghklnpqstvxyz',
133 auth_type => 'UNIF_TITLE',
134 subfields => 'adfghklmnoprstvxyz',
137 '648' => { auth_type => 'CHRON_TERM', subfields => 'avxyz', subject => 1 },
138 '650' => { auth_type => 'TOPIC_TERM', subfields => 'abvxyz', subject => 1 },
139 '651' => { auth_type => 'GEOGR_NAME', subfields => 'avxyz', subject => 1 },
140 '655' => { auth_type => 'GENRE/FORM', subfields => 'avxyz', subject => 1 },
141 '690' => { auth_type => 'TOPIC_TERM', subfields => 'abvxyz', subject => 1 },
142 '691' => { auth_type => 'GEOGR_NAME', subfields => 'avxyz', subject => 1 },
143 '696' => { auth_type => 'PERSO_NAME', subfields => 'abcdfghjklmnopqrst' },
144 '697' => { auth_type => 'CORPO_NAME', subfields => 'abcdfghklmnoprst' },
145 '698' => { auth_type => 'MEETI_NAME', subfields => 'acdfghjklnpqst' },
146 '699' => { auth_type => 'UNIF_TITLE', subfields => 'adfghklmnoprst' },
147 '700' => { auth_type => 'PERSO_NAME', subfields => 'abcdfghjklmnopqrst' },
148 '710' => { auth_type => 'CORPO_NAME', subfields => 'abcdfghklmnoprst' },
149 '711' => { auth_type => 'MEETI_NAME', subfields => 'acdefghklnpqst' },
150 '730' => { auth_type => 'UNIF_TITLE', subfields => 'adfghklmnoprst' },
152 auth_type => 'PERSO_NAME',
153 subfields => 'abcdfghjklmnopqrst',
157 auth_type => 'CORPO_NAME',
158 subfields => 'abcdfghklmnoprst',
162 { auth_type => 'MEETI_NAME', subfields => 'acdefghklnpqst', series => 1 },
164 { auth_type => 'UNIF_TITLE', subfields => 'adfghklmnoprst', series => 1 },
167 my $auth_heading_fields = {
169 auth_type => 'PERSO_NAME',
170 subfields => 'abcdfghjklmnopqrstvxyz68',
174 auth_type => 'CORPO_NAME',
175 subfields => 'abcdfghklmnoprstvxyz68',
179 auth_type => 'MEETI_NAME',
180 subfields => 'acdefghklnpqstvxyz68',
184 auth_type => 'UNIF_TITLE',
185 subfields => 'adfghklmnoprstvxyz68',
189 auth_type => 'NAME_EVENT',
190 subfields => 'acdgvxyz68',
194 auth_type => 'CHRON_TERM',
195 subfields => 'abvxyz68',
199 auth_type => 'TOPIC_TERM',
200 subfields => 'abvxyz68',
204 auth_type => 'GEOG_NAME',
205 subfields => 'avxyz68',
209 auth_type => 'GENRE/FORM',
210 subfields => 'abvxyz68',
214 auth_type => 'MED_PERFRM',
219 auth_type => 'TOPIC_TERM',
220 subfields => 'vxyz68',
223 auth_type => 'GEOGR_NAME',
224 subfields => 'vxyz68',
227 auth_type => 'CHRON_TERM',
228 subfields => 'vxyz68',
231 auth_type => 'GENRE/FORM',
232 subfields => 'vxyz68',
242 'x' => 'generalsubdiv',
243 'y' => 'chronologicalsubdiv',
244 'z' => 'geographicsubdiv',
251 my $marc_handler = C4::Heading::MARC21->new();
257 return bless {}, $class;
260 =head2 valid_heading_tag
264 sub valid_heading_tag {
267 my $frameworkcode = shift;
269 my $heading_fields = $auth ? { %$auth_heading_fields } : { %$bib_heading_fields };
271 if ( exists $heading_fields->{$tag} ) {
280 =head2 valid_heading_subfield
284 sub valid_heading_subfield {
287 my $subfield = shift;
290 my $heading_fields = $auth ? { %$auth_heading_fields } : { %$bib_heading_fields };
292 if ( exists $heading_fields->{$tag} ) {
293 return 1 if ($heading_fields->{$tag}->{subfields} =~ /$subfield/);
298 =head2 get_valid_bib_heading_subfields
302 sub get_valid_bib_heading_subfields {
306 return $bib_heading_fields->{$tag}->{subfields} // undef;
309 =head2 get_auth_heading_subfields_to_report
313 sub get_auth_heading_subfields_to_report {
317 my $subfields = $auth_heading_fields->{$tag}->{subfields} // '';
318 $subfields =~ s/[68]//;
324 Given a field and an indicator to specify if it is an authority field or biblio field we return
325 the correct type, thesauarus, search form, and display form of the heading.
334 my $tag = $field->tag;
335 my $heading_fields = $auth ? { %$auth_heading_fields } : { %$bib_heading_fields };
337 my $field_info = $heading_fields->{$tag};
338 my $auth_type = $field_info->{'auth_type'};
341 ? _get_subject_thesaurus($field)
342 : "lcsh"; # use 'lcsh' for names, UT, etc.
344 _get_search_heading( $field, $field_info->{'subfields'} );
345 my $display_heading =
346 _get_display_heading( $field, $field_info->{'subfields'} );
348 return ( $auth_type, $thesaurus, $search_heading, $display_heading,
352 =head1 INTERNAL FUNCTIONS
354 =head2 _get_subject_thesaurus
358 sub _get_subject_thesaurus {
360 my $ind2 = $field->indicator(2);
362 my $thesaurus = "notdefined";
363 if ( $ind2 eq '0' ) {
366 elsif ( $ind2 eq '1' ) {
369 elsif ( $ind2 eq '2' ) {
372 elsif ( $ind2 eq '3' ) {
375 elsif ( $ind2 eq '4' ) {
376 $thesaurus = "notspecified";
378 elsif ( $ind2 eq '5' ) {
381 elsif ( $ind2 eq '6' ) {
384 elsif ( $ind2 eq '7' ) {
385 my $sf2 = $field->subfield('2');
386 $thesaurus = $sf2 if defined($sf2);
392 =head2 _get_search_heading
396 sub _get_search_heading {
398 my $subfields = shift;
401 my @subfields = $field->subfields();
403 for ( my $i = 0 ; $i <= $#subfields ; $i++ ) {
404 my $code = $subfields[$i]->[0];
405 my $code_re = quotemeta $code;
406 my $value = $subfields[$i]->[1];
407 $value =~ s/[\s]*[-,.:=;!%\/][\s]*$//;
408 next unless $subfields =~ qr/$code_re/;
414 if ( exists $subdivisions{$code} ) {
415 $heading .= " $subdivisions{$code} $value";
418 $heading .= " $value";
423 # remove characters that are part of CCL syntax
424 $heading =~ s/[)(=]//g;
429 =head2 _get_display_heading
433 sub _get_display_heading {
435 my $subfields = shift;
438 my @subfields = $field->subfields();
440 for ( my $i = 0 ; $i <= $#subfields ; $i++ ) {
441 my $code = $subfields[$i]->[0];
442 my $code_re = quotemeta $code;
443 my $value = $subfields[$i]->[1];
444 next unless $subfields =~ qr/$code_re/;
450 if ( exists $subdivisions{$code} ) {
451 $heading .= "--$value";
454 $heading .= " $value";
461 # Additional limiters that we aren't using:
462 # if ($self->{'subject_added_entry'}) {
463 # $limiters .= " AND Heading-use-subject-added-entry=a";
465 # if ($self->{'series_added_entry'}) {
466 # $limiters .= " AND Heading-use-series-added-entry=a";
468 # if (not $self->{'subject_added_entry'} and not $self->{'series_added_entry'}) {
469 # $limiters .= " AND Heading-use-main-or-added-entry=a"
474 Koha Development Team <http://koha-community.org/>
476 Galen Charlton <galen.charlton@liblime.com>