Bug 15288: (followup) Better wording for OPAC error page
[koha.git] / C4 / Heading / MARC21.pm
blobe6a8ed328be87d0e93030b6ba5d40db24c64a52a
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>.
20 use strict;
21 use warnings;
22 use MARC::Record;
23 use MARC::Field;
25 our $VERSION = 3.07.00.049;
27 =head1 NAME
29 C4::Heading::MARC21
31 =head1 SYNOPSIS
33 use C4::Heading::MARC21;
35 =head1 DESCRIPTION
37 This is an internal helper class used by
38 C<C4::Heading> to parse headings data from
39 MARC21 records. Object of this type
40 do not carry data, instead, they only
41 dispatch functions.
43 =head1 DATA STRUCTURES
45 FIXME - this should be moved to a configuration file.
47 =head2 bib_heading_fields
49 =cut
51 my $bib_heading_fields = {
52 '100' => {
53 auth_type => 'PERSO_NAME',
54 subfields => 'abcdfghjklmnopqrst',
55 main_entry => 1
57 '110' => {
58 auth_type => 'CORPO_NAME',
59 subfields => 'abcdfghklmnoprst',
60 main_entry => 1
62 '111' => {
63 auth_type => 'MEETI_NAME',
64 subfields => 'acdfghjklnpqst',
65 main_entry => 1
67 '130' => {
68 auth_type => 'UNIF_TITLE',
69 subfields => 'adfghklmnoprst',
70 main_entry => 1
72 '440' => { auth_type => 'UNIF_TITLE', subfields => 'anp', series => 1 },
73 '600' => {
74 auth_type => 'PERSO_NAME',
75 subfields => 'abcdfghjklmnopqrstvxyz',
76 subject => 1
78 '610' => {
79 auth_type => 'CORPO_NAME',
80 subfields => 'abcdfghklmnoprstvxyz',
81 subject => 1
83 '611' => {
84 auth_type => 'MEETI_NAME',
85 subfields => 'acdfghjklnpqstvxyz',
86 subject => 1
88 '630' => {
89 auth_type => 'UNIF_TITLE',
90 subfields => 'adfghklmnoprstvxyz',
91 subject => 1
93 '648' => { auth_type => 'CHRON_TERM', subfields => 'avxyz', subject => 1 },
94 '650' => { auth_type => 'TOPIC_TERM', subfields => 'abvxyz', subject => 1 },
95 '651' => { auth_type => 'GEOGR_NAME', subfields => 'avxyz', subject => 1 },
96 '655' => { auth_type => 'GENRE/FORM', subfields => 'avxyz', subject => 1 },
97 '690' => { auth_type => 'TOPIC_TERM', subfields => 'abvxyz', subject => 1 },
98 '691' => { auth_type => 'GEOGR_NAME', subfields => 'avxyz', subject => 1 },
99 '696' => { auth_type => 'PERSO_NAME', subfields => 'abcdfghjklmnopqrst' },
100 '697' => { auth_type => 'CORPO_NAME', subfields => 'abcdfghklmnoprst' },
101 '698' => { auth_type => 'MEETI_NAME', subfields => 'acdfghjklnpqst' },
102 '699' => { auth_type => 'UNIF_TITLE', subfields => 'adfghklmnoprst' },
103 '700' => { auth_type => 'PERSO_NAME', subfields => 'abcdfghjklmnopqrst' },
104 '710' => { auth_type => 'CORPO_NAME', subfields => 'abcdfghklmnoprst' },
105 '711' => { auth_type => 'MEETI_NAME', subfields => 'acdfghjklnpqst' },
106 '730' => { auth_type => 'UNIF_TITLE', subfields => 'adfghklmnoprst' },
107 '800' => {
108 auth_type => 'PERSO_NAME',
109 subfields => 'abcdfghjklmnopqrst',
110 series => 1
112 '810' => {
113 auth_type => 'CORPO_NAME',
114 subfields => 'abcdfghklmnoprst',
115 series => 1
117 '811' =>
118 { auth_type => 'MEETI_NAME', subfields => 'acdfghjklnpqst', series => 1 },
119 '830' =>
120 { auth_type => 'UNIF_TITLE', subfields => 'adfghklmnoprst', series => 1 },
123 =head2 subdivisions
125 =cut
127 my %subdivisions = (
128 'v' => 'formsubdiv',
129 'x' => 'generalsubdiv',
130 'y' => 'chronologicalsubdiv',
131 'z' => 'geographicsubdiv',
134 =head1 METHODS
136 =head2 new
138 my $marc_handler = C4::Heading::MARC21->new();
140 =cut
142 sub new {
143 my $class = shift;
144 return bless {}, $class;
147 =head2 valid_bib_heading_tag
149 =cut
151 sub valid_bib_heading_tag {
152 my $self = shift;
153 my $tag = shift;
154 my $frameworkcode = shift;
156 if ( exists $bib_heading_fields->{$tag} ) {
157 return 1;
159 else {
160 return 0;
165 =head2 parse_heading
167 =cut
169 sub parse_heading {
170 my $self = shift;
171 my $field = shift;
173 my $tag = $field->tag;
174 my $field_info = $bib_heading_fields->{$tag};
176 my $auth_type = $field_info->{'auth_type'};
177 my $thesaurus =
178 $tag =~ m/6../
179 ? _get_subject_thesaurus($field)
180 : "lcsh"; # use 'lcsh' for names, UT, etc.
181 my $search_heading =
182 _get_search_heading( $field, $field_info->{'subfields'} );
183 my $display_heading =
184 _get_display_heading( $field, $field_info->{'subfields'} );
186 return ( $auth_type, $thesaurus, $search_heading, $display_heading,
187 'exact' );
190 =head1 INTERNAL FUNCTIONS
192 =head2 _get_subject_thesaurus
194 =cut
196 sub _get_subject_thesaurus {
197 my $field = shift;
198 my $ind2 = $field->indicator(2);
200 my $thesaurus = "notdefined";
201 if ( $ind2 eq '0' ) {
202 $thesaurus = "lcsh";
204 elsif ( $ind2 eq '1' ) {
205 $thesaurus = "lcac";
207 elsif ( $ind2 eq '2' ) {
208 $thesaurus = "mesh";
210 elsif ( $ind2 eq '3' ) {
211 $thesaurus = "nal";
213 elsif ( $ind2 eq '4' ) {
214 $thesaurus = "notspecified";
216 elsif ( $ind2 eq '5' ) {
217 $thesaurus = "cash";
219 elsif ( $ind2 eq '6' ) {
220 $thesaurus = "rvm";
222 elsif ( $ind2 eq '7' ) {
223 my $sf2 = $field->subfield('2');
224 $thesaurus = $sf2 if defined($sf2);
227 return $thesaurus;
230 =head2 _get_search_heading
232 =cut
234 sub _get_search_heading {
235 my $field = shift;
236 my $subfields = shift;
238 my $heading = "";
239 my @subfields = $field->subfields();
240 my $first = 1;
241 for ( my $i = 0 ; $i <= $#subfields ; $i++ ) {
242 my $code = $subfields[$i]->[0];
243 my $code_re = quotemeta $code;
244 my $value = $subfields[$i]->[1];
245 $value =~ s/[-,.:=;!%\/]$//;
246 next unless $subfields =~ qr/$code_re/;
247 if ($first) {
248 $first = 0;
249 $heading = $value;
251 else {
252 if ( exists $subdivisions{$code} ) {
253 $heading .= " $subdivisions{$code} $value";
255 else {
256 $heading .= " $value";
261 # remove characters that are part of CCL syntax
262 $heading =~ s/[)(=]//g;
264 return $heading;
267 =head2 _get_display_heading
269 =cut
271 sub _get_display_heading {
272 my $field = shift;
273 my $subfields = shift;
275 my $heading = "";
276 my @subfields = $field->subfields();
277 my $first = 1;
278 for ( my $i = 0 ; $i <= $#subfields ; $i++ ) {
279 my $code = $subfields[$i]->[0];
280 my $code_re = quotemeta $code;
281 my $value = $subfields[$i]->[1];
282 next unless $subfields =~ qr/$code_re/;
283 if ($first) {
284 $first = 0;
285 $heading = $value;
287 else {
288 if ( exists $subdivisions{$code} ) {
289 $heading .= "--$value";
291 else {
292 $heading .= " $value";
296 return $heading;
299 # Additional limiters that we aren't using:
300 # if ($self->{'subject_added_entry'}) {
301 # $limiters .= " AND Heading-use-subject-added-entry=a";
303 # if ($self->{'series_added_entry'}) {
304 # $limiters .= " AND Heading-use-series-added-entry=a";
306 # if (not $self->{'subject_added_entry'} and not $self->{'series_added_entry'}) {
307 # $limiters .= " AND Heading-use-main-or-added-entry=a"
310 =head1 AUTHOR
312 Koha Development Team <http://koha-community.org/>
314 Galen Charlton <galen.charlton@liblime.com>
316 =cut