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>.
32 use C4::Heading::MARC21;
36 This is an internal helper class used by
37 C<C4::Heading> to parse headings data from
38 MARC21 records. Object of this type
39 do not carry data, instead, they only
42 =head1 DATA STRUCTURES
44 FIXME - this should be moved to a configuration file.
46 =head2 bib_heading_fields
50 my $bib_heading_fields = {
52 auth_type
=> 'PERSO_NAME',
53 subfields
=> 'abcdfghjklmnopqrst',
57 auth_type
=> 'CORPO_NAME',
58 subfields
=> 'abcdfghklmnoprst',
62 auth_type
=> 'MEETI_NAME',
63 subfields
=> 'acdfghjklnpqst',
67 auth_type
=> 'UNIF_TITLE',
68 subfields
=> 'adfghklmnoprst',
71 '440' => { auth_type
=> 'UNIF_TITLE', subfields
=> 'anp', series
=> 1 },
73 auth_type
=> 'PERSO_NAME',
74 subfields
=> 'abcdfghjklmnopqrstvxyz',
78 auth_type
=> 'CORPO_NAME',
79 subfields
=> 'abcdfghklmnoprstvxyz',
83 auth_type
=> 'MEETI_NAME',
84 subfields
=> 'acdfghjklnpqstvxyz',
88 auth_type
=> 'UNIF_TITLE',
89 subfields
=> 'adfghklmnoprstvxyz',
92 '648' => { auth_type
=> 'CHRON_TERM', subfields
=> 'avxyz', subject
=> 1 },
93 '650' => { auth_type
=> 'TOPIC_TERM', subfields
=> 'abvxyz', subject
=> 1 },
94 '651' => { auth_type
=> 'GEOGR_NAME', subfields
=> 'avxyz', subject
=> 1 },
95 '655' => { auth_type
=> 'GENRE/FORM', subfields
=> 'avxyz', subject
=> 1 },
96 '690' => { auth_type
=> 'TOPIC_TERM', subfields
=> 'abvxyz', subject
=> 1 },
97 '691' => { auth_type
=> 'GEOGR_NAME', subfields
=> 'avxyz', subject
=> 1 },
98 '696' => { auth_type
=> 'PERSO_NAME', subfields
=> 'abcdfghjklmnopqrst' },
99 '697' => { auth_type
=> 'CORPO_NAME', subfields
=> 'abcdfghklmnoprst' },
100 '698' => { auth_type
=> 'MEETI_NAME', subfields
=> 'acdfghjklnpqst' },
101 '699' => { auth_type
=> 'UNIF_TITLE', subfields
=> 'adfghklmnoprst' },
102 '700' => { auth_type
=> 'PERSO_NAME', subfields
=> 'abcdfghjklmnopqrst' },
103 '710' => { auth_type
=> 'CORPO_NAME', subfields
=> 'abcdfghklmnoprst' },
104 '711' => { auth_type
=> 'MEETI_NAME', subfields
=> 'acdfghjklnpqst' },
105 '730' => { auth_type
=> 'UNIF_TITLE', subfields
=> 'adfghklmnoprst' },
107 auth_type
=> 'PERSO_NAME',
108 subfields
=> 'abcdfghjklmnopqrst',
112 auth_type
=> 'CORPO_NAME',
113 subfields
=> 'abcdfghklmnoprst',
117 { auth_type
=> 'MEETI_NAME', subfields
=> 'acdfghjklnpqst', series
=> 1 },
119 { auth_type
=> 'UNIF_TITLE', subfields
=> 'adfghklmnoprst', series
=> 1 },
122 my $auth_heading_fields = {
124 auth_type
=> 'PERSO_NAME',
125 subfields
=> 'abcdfghjklmnopqrstvxyz',
129 auth_type
=> 'CORPO_NAME',
130 subfields
=> 'abcdfghklmnoprstvxyz',
134 auth_type
=> 'MEETI_NAME',
135 subfields
=> 'acdfghjklnpqstvxyz',
139 auth_type
=> 'UNIF_TITLE',
140 subfields
=> 'adfghklmnoprstvxyz',
144 auth_type
=> 'CHRON_TERM',
145 subfields
=> 'avxyz',
149 auth_type
=> 'TOPIC_TERM',
150 subfields
=> 'abgvxyz',
154 auth_type
=> 'GEOG_NAME',
155 subfields
=> 'agvxyz',
159 auth_type
=> 'GENRE/FORM',
160 subfields
=> 'agvxyz',
171 'x' => 'generalsubdiv',
172 'y' => 'chronologicalsubdiv',
173 'z' => 'geographicsubdiv',
180 my $marc_handler = C4::Heading::MARC21->new();
186 return bless {}, $class;
189 =head2 valid_heading_tag
193 sub valid_heading_tag
{
196 my $frameworkcode = shift;
198 my $heading_fields = $auth ?
{ %$auth_heading_fields } : { %$bib_heading_fields };
200 if ( exists $heading_fields->{$tag} ) {
209 =head2 valid_heading_subfield
213 sub valid_heading_subfield
{
216 my $subfield = shift;
219 my $heading_fields = $auth ?
{ %$auth_heading_fields } : { %$bib_heading_fields };
221 if ( exists $heading_fields->{$tag} ) {
222 return 1 if ($heading_fields->{$tag}->{subfields
} =~ /$subfield/);
229 Given a field and an indicator to specify if it is an authority field or biblio field we return
230 the correct type, thesauarus, search form, and display form of the heading.
239 my $tag = $field->tag;
240 my $heading_fields = $auth ?
{ %$auth_heading_fields } : { %$bib_heading_fields };
242 my $field_info = $heading_fields->{$tag};
243 my $auth_type = $field_info->{'auth_type'};
246 ? _get_subject_thesaurus
($field)
247 : "lcsh"; # use 'lcsh' for names, UT, etc.
249 _get_search_heading
( $field, $field_info->{'subfields'} );
250 my $display_heading =
251 _get_display_heading
( $field, $field_info->{'subfields'} );
253 return ( $auth_type, $thesaurus, $search_heading, $display_heading,
257 =head1 INTERNAL FUNCTIONS
259 =head2 _get_subject_thesaurus
263 sub _get_subject_thesaurus
{
265 my $ind2 = $field->indicator(2);
267 my $thesaurus = "notdefined";
268 if ( $ind2 eq '0' ) {
271 elsif ( $ind2 eq '1' ) {
274 elsif ( $ind2 eq '2' ) {
277 elsif ( $ind2 eq '3' ) {
280 elsif ( $ind2 eq '4' ) {
281 $thesaurus = "notspecified";
283 elsif ( $ind2 eq '5' ) {
286 elsif ( $ind2 eq '6' ) {
289 elsif ( $ind2 eq '7' ) {
290 my $sf2 = $field->subfield('2');
291 $thesaurus = $sf2 if defined($sf2);
297 =head2 _get_search_heading
301 sub _get_search_heading
{
303 my $subfields = shift;
306 my @subfields = $field->subfields();
308 for ( my $i = 0 ; $i <= $#subfields ; $i++ ) {
309 my $code = $subfields[$i]->[0];
310 my $code_re = quotemeta $code;
311 my $value = $subfields[$i]->[1];
312 $value =~ s/[\s]*[-,.:=;!%\/][\s]*$//;
313 next unless $subfields =~ qr/$code_re/;
319 if ( exists $subdivisions{$code} ) {
320 $heading .= " $subdivisions{$code} $value";
323 $heading .= " $value";
328 # remove characters that are part of CCL syntax
329 $heading =~ s/[)(=]//g;
334 =head2 _get_display_heading
338 sub _get_display_heading
{
340 my $subfields = shift;
343 my @subfields = $field->subfields();
345 for ( my $i = 0 ; $i <= $#subfields ; $i++ ) {
346 my $code = $subfields[$i]->[0];
347 my $code_re = quotemeta $code;
348 my $value = $subfields[$i]->[1];
349 next unless $subfields =~ qr/$code_re/;
355 if ( exists $subdivisions{$code} ) {
356 $heading .= "--$value";
359 $heading .= " $value";
366 # Additional limiters that we aren't using:
367 # if ($self->{'subject_added_entry'}) {
368 # $limiters .= " AND Heading-use-subject-added-entry=a";
370 # if ($self->{'series_added_entry'}) {
371 # $limiters .= " AND Heading-use-series-added-entry=a";
373 # if (not $self->{'subject_added_entry'} and not $self->{'series_added_entry'}) {
374 # $limiters .= " AND Heading-use-main-or-added-entry=a"
379 Koha Development Team <http://koha-community.org/>
381 Galen Charlton <galen.charlton@liblime.com>