View | Details | Raw Unified | Return to bug 24269
Collapse All | Expand All

(-)a/C4/Biblio.pm (-2 / +3 lines)
Lines 502-509 sub LinkBibHeadingsToAuthorities { Link Here
502
    $allowrelink = 1 unless defined $allowrelink;
502
    $allowrelink = 1 unless defined $allowrelink;
503
    my $num_headings_changed = 0;
503
    my $num_headings_changed = 0;
504
    foreach my $field ( $bib->fields() ) {
504
    foreach my $field ( $bib->fields() ) {
505
        my $heading = C4::Heading->new_from_bib_field( $field, $frameworkcode );
505
        my $heading = C4::Heading->new_from_field( $field, $frameworkcode );
506
        next unless defined $heading;
506
        next unless defined $heading;
507
        warn $heading->search_form;
507
508
508
        # check existing $9
509
        # check existing $9
509
        my $current_link = $field->subfield('9');
510
        my $current_link = $field->subfield('9');
Lines 549-555 sub LinkBibHeadingsToAuthorities { Link Here
549
                    map {
550
                    map {
550
                        $authfield->add_subfields( $_->[0] => $_->[1] )
551
                        $authfield->add_subfields( $_->[0] => $_->[1] )
551
                          if ( $_->[0] =~ /[A-z]/ && $_->[0] ne "a"
552
                          if ( $_->[0] =~ /[A-z]/ && $_->[0] ne "a"
552
                            && C4::Heading::valid_bib_heading_subfield(
553
                            && C4::Heading::valid_heading_subfield(
553
                                $authority_type->auth_tag_to_report, $_->[0] )
554
                                $authority_type->auth_tag_to_report, $_->[0] )
554
                            );
555
                            );
555
                    } $field->subfields();
556
                    } $field->subfields();
(-)a/C4/Heading.pm (-14 / +16 lines)
Lines 33-39 C4::Heading Link Here
33
=head1 SYNOPSIS
33
=head1 SYNOPSIS
34
34
35
 use C4::Heading;
35
 use C4::Heading;
36
 my $heading = C4::Heading->new_from_bib_field($field, $frameworkcode);
36
 my $heading = C4::Heading->new_from_field($field, $frameworkcode);
37
 my $thesaurus = $heading->thesaurus();
37
 my $thesaurus = $heading->thesaurus();
38
 my $type = $heading->type();
38
 my $type = $heading->type();
39
 my $display_heading = $heading->display_form();
39
 my $display_heading = $heading->display_form();
Lines 46-54 headings found in bibliographic and authority records. Link Here
46
46
47
=head1 METHODS
47
=head1 METHODS
48
48
49
=head2 new_from_bib_field
49
=head2 new_from_field
50
50
51
  my $heading = C4::Heading->new_from_bib_field($field, $frameworkcode, [, $marc_flavour]);
51
  my $heading = C4::Heading->new_from_field($field, $frameworkcode, [, $marc_flavour]);
52
52
53
Given a C<MARC::Field> object containing a heading from a 
53
Given a C<MARC::Field> object containing a heading from a 
54
bib record, create a C<C4::Heading> object.
54
bib record, create a C<C4::Heading> object.
Lines 57-77 The optional second parameter is the MARC flavour (i.e., MARC21 Link Here
57
or UNIMARC); if this parameter is not supplied, it is
57
or UNIMARC); if this parameter is not supplied, it is
58
taken from the Koha application context.
58
taken from the Koha application context.
59
59
60
The optional third parameter is 'auth' - it is handled as boolean. If supplied we treat the field as an auth record field. Otherwise if it is a bib field.
61
60
If the MARC field supplied is not a valid heading, undef
62
If the MARC field supplied is not a valid heading, undef
61
is returned.
63
is returned.
62
64
63
=cut
65
=cut
64
66
65
sub new_from_bib_field {
67
sub new_from_field {
66
    my $class         = shift;
68
    my $class         = shift;
67
    my $field         = shift;
69
    my $field         = shift;
68
    my $frameworkcode = shift;
70
    my $frameworkcode = shift;
69
    my $marcflavour   = @_ ? shift : C4::Context->preference('marcflavour');
71
    my $auth          = shift;
70
72
    my $marcflavour   = C4::Context->preference('marcflavour');
71
    my $marc_handler = _marc_format_handler($marcflavour);
73
    my $marc_handler = _marc_format_handler($marcflavour);
72
74
73
    my $tag = $field->tag();
75
    my $tag = $field->tag();
74
    return unless $marc_handler->valid_bib_heading_tag( $tag, $frameworkcode );
76
    return unless $marc_handler->valid_heading_tag( $tag, $frameworkcode, $auth );
75
    my $self = {};
77
    my $self = {};
76
78
77
    $self->{'field'} = $field;
79
    $self->{'field'} = $field;
Lines 79-85 sub new_from_bib_field { Link Here
79
        $self->{'auth_type'},   $self->{'thesaurus'},
81
        $self->{'auth_type'},   $self->{'thesaurus'},
80
        $self->{'search_form'}, $self->{'display_form'},
82
        $self->{'search_form'}, $self->{'display_form'},
81
        $self->{'match_type'}
83
        $self->{'match_type'}
82
    ) = $marc_handler->parse_heading($field);
84
    ) = $marc_handler->parse_heading($field, $auth );
83
85
84
    bless $self, $class;
86
    bless $self, $class;
85
    return $self;
87
    return $self;
Lines 170-189 sub preferred_authorities { Link Here
170
    return $results;
172
    return $results;
171
}
173
}
172
174
173
=head2 valid_bib_heading_subfield
175
=head2 valid_heading_subfield
174
176
175
    if (C4::Heading::valid_bib_heading_subfield('100', 'e', '')) ...
177
    if (C4::Heading::valid_heading_subfield('100', 'e', '')) ...
176
178
177
=cut
179
=cut
178
180
179
sub valid_bib_heading_subfield {
181
sub valid_heading_subfield {
180
    my $tag           = shift;
182
    my $tag           = shift;
181
    my $subfield      = shift;
183
    my $subfield      = shift;
182
    my $marcflavour   = @_ ? shift : C4::Context->preference('marcflavour');
184
    my $marcflavour   = C4::Context->preference('marcflavour');
185
    my $auth          = shift;
183
186
184
    my $marc_handler = _marc_format_handler($marcflavour);
187
    my $marc_handler = _marc_format_handler($marcflavour);
185
188
    return $marc_handler->valid_heading_subfield( $tag, $subfield, $auth );
186
    return $marc_handler->valid_bib_heading_subfield( $tag, $subfield );
187
}
189
}
188
190
189
=head1 INTERNAL METHODS
191
=head1 INTERNAL METHODS
(-)a/C4/Heading/MARC21.pm (-8 / +58 lines)
Lines 119-124 my $bib_heading_fields = { Link Here
119
      { auth_type => 'UNIF_TITLE', subfields => 'adfghklmnoprst', series => 1 },
119
      { auth_type => 'UNIF_TITLE', subfields => 'adfghklmnoprst', series => 1 },
120
};
120
};
121
121
122
my $auth_heading_fields = {
123
    '100' => {
124
        auth_type  => 'PERSO_NAME',
125
        subfields  => 'abcdfghjklmnopqrstvxyz',
126
        main_entry => 1
127
    },
128
    '110' => {
129
        auth_type  => 'CORPO_NAME',
130
        subfields  => 'abcdfghklmnoprstvxyz',
131
        main_entry => 1
132
    },
133
    '111' => {
134
        auth_type  => 'MEETI_NAME',
135
        subfields  => 'acdfghjklnpqstvxyz',
136
        main_entry => 1
137
    },
138
    '130' => {
139
        auth_type  => 'UNIF_TITLE',
140
        subfields  => 'adfghklmnoprstvxyz',
141
        main_entry => 1
142
    },
143
    '148' => {
144
        auth_type => 'CHRON_TERM',
145
        subfields => 'avxyz',
146
        main_entry => 1
147
    },
148
    '150' => {
149
        auth_type => 'TOPIC_TERM',
150
        subfields => 'abgvxyz',
151
        main_entry => 1
152
    },
153
    '151' => {
154
        auth_type => 'GEOG_NAME',
155
        subfields => 'agvxyz',
156
        main_entry => 1
157
    },
158
    '155' => {
159
        auth_type => 'GENRE/FORM',
160
        subfields => 'agvxyz',
161
        main_entry => 1
162
    }
163
};
164
122
=head2 subdivisions
165
=head2 subdivisions
123
166
124
=cut
167
=cut
Lines 143-158 sub new { Link Here
143
    return bless {}, $class;
186
    return bless {}, $class;
144
}
187
}
145
188
146
=head2 valid_bib_heading_tag
189
=head2 valid_heading_tag
147
190
148
=cut
191
=cut
149
192
150
sub valid_bib_heading_tag {
193
sub valid_heading_tag {
151
    my $self          = shift;
194
    my $self          = shift;
152
    my $tag           = shift;
195
    my $tag           = shift;
153
    my $frameworkcode = shift;
196
    my $frameworkcode = shift;
197
    my $auth          = shift;
198
    my $heading_fields = $auth ? { %$auth_heading_fields } : { %$bib_heading_fields };
154
199
155
    if ( exists $bib_heading_fields->{$tag} ) {
200
    if ( exists $heading_fields->{$tag} ) {
156
        return 1;
201
        return 1;
157
    }
202
    }
158
    else {
203
    else {
Lines 161-177 sub valid_bib_heading_tag { Link Here
161
206
162
}
207
}
163
208
164
=head2 valid_bib_heading_subfield
209
=head2 valid_heading_subfield
165
210
166
=cut
211
=cut
167
212
168
sub valid_bib_heading_subfield {
213
sub valid_heading_subfield {
169
    my $self          = shift;
214
    my $self          = shift;
170
    my $tag           = shift;
215
    my $tag           = shift;
171
    my $subfield      = shift;
216
    my $subfield      = shift;
217
    my $auth          = shift;
218
219
    my $heading_fields = $auth ? { %$auth_heading_fields } : { %$bib_heading_fields };
172
220
173
    if ( exists $bib_heading_fields->{$tag} ) {
221
    if ( exists $heading_fields->{$tag} ) {
174
        return 1 if ($bib_heading_fields->{$tag}->{subfields} =~ /$subfield/);
222
        return 1 if ($heading_fields->{$tag}->{subfields} =~ /$subfield/);
175
    }
223
    }
176
    return 0;
224
    return 0;
177
}
225
}
Lines 183-192 sub valid_bib_heading_subfield { Link Here
183
sub parse_heading {
231
sub parse_heading {
184
    my $self  = shift;
232
    my $self  = shift;
185
    my $field = shift;
233
    my $field = shift;
234
    my $auth  = shift;
186
235
187
    my $tag        = $field->tag;
236
    my $tag        = $field->tag;
188
    my $field_info = $bib_heading_fields->{$tag};
237
    my $heading_fields = $auth ? { %$auth_heading_fields } : { %$bib_heading_fields };
189
238
239
    my $field_info = $heading_fields->{$tag};
190
    my $auth_type = $field_info->{'auth_type'};
240
    my $auth_type = $field_info->{'auth_type'};
191
    my $thesaurus =
241
    my $thesaurus =
192
      $tag =~ m/6../
242
      $tag =~ m/6../
(-)a/C4/Heading/UNIMARC.pm (-3 / +3 lines)
Lines 91-106 sub new { Link Here
91
91
92
=cut
92
=cut
93
93
94
sub valid_bib_heading_tag {
94
sub valid_heading_tag {
95
    my ( $self, $tag ) = @_;
95
    my ( $self, $tag ) = @_;
96
    return $bib_heading_fields->{$tag};
96
    return $bib_heading_fields->{$tag};
97
}
97
}
98
98
99
=head2 valid_bib_heading_subfield
99
=head2 valid_heading_subfield
100
100
101
=cut
101
=cut
102
102
103
sub valid_bib_heading_subfield {
103
sub valid_heading_subfield {
104
    my $self          = shift;
104
    my $self          = shift;
105
    my $tag           = shift;
105
    my $tag           = shift;
106
    my $subfield      = shift;
106
    my $subfield      = shift;
(-)a/C4/Linker/Default.pm (-1 / +1 lines)
Lines 68-74 sub get_link { Link Here
68
                        map { $_->[0] => $_->[1] } @subfields
68
                        map { $_->[0] => $_->[1] } @subfields
69
                    );
69
                    );
70
                ( $authid, $fuzzy ) =
70
                ( $authid, $fuzzy ) =
71
                  $self->get_link( C4::Heading->new_from_bib_field($field),
71
                  $self->get_link( C4::Heading->new_from_field($field),
72
                    $behavior );
72
                    $behavior );
73
            }
73
            }
74
        }
74
        }
(-)a/Koha/SearchEngine/Elasticsearch.pm (-1 / +13 lines)
Lines 26-31 use Koha::Exceptions::Config; Link Here
26
use Koha::Exceptions::Elasticsearch;
26
use Koha::Exceptions::Elasticsearch;
27
use Koha::SearchFields;
27
use Koha::SearchFields;
28
use Koha::SearchMarcMaps;
28
use Koha::SearchMarcMaps;
29
use C4::Heading;
29
30
30
use Carp;
31
use Carp;
31
use Clone qw(clone);
32
use Clone qw(clone);
Lines 470-476 sub marc_records_to_documents { Link Here
470
                }
471
                }
471
472
472
                my $data_field_rules = $data_fields_rules->{$tag};
473
                my $data_field_rules = $data_fields_rules->{$tag};
473
474
                if ($data_field_rules) {
474
                if ($data_field_rules) {
475
                    my $subfields_mappings = $data_field_rules->{subfields};
475
                    my $subfields_mappings = $data_field_rules->{subfields};
476
                    my $wildcard_mappings = $subfields_mappings->{'*'};
476
                    my $wildcard_mappings = $subfields_mappings->{'*'};
Lines 483-488 sub marc_records_to_documents { Link Here
483
                        if (@{$mappings}) {
483
                        if (@{$mappings}) {
484
                            $self->_process_mappings($mappings, $data, $record_document, $altscript);
484
                            $self->_process_mappings($mappings, $data, $record_document, $altscript);
485
                        }
485
                        }
486
                        if ( grep /match-heading/, @{$mappings} ){
487
                            my $matcher = C4::Heading->new_from_field( $field, undef, 1 ); #new auth heading
488
                            next unless $matcher;
489
                            push @{$record_document->{'match-heading'}}, $matcher->search_form;
490
                            push @{$record_document->{'display_form'}}, $matcher->display_form;
491
                        }
486
                    }
492
                    }
487
493
488
                    my $subfields_join_mappings = $data_field_rules->{subfields_join};
494
                    my $subfields_join_mappings = $data_field_rules->{subfields_join};
Lines 499-504 sub marc_records_to_documents { Link Here
499
                            if ($data) {
505
                            if ($data) {
500
                                $self->_process_mappings($subfields_join_mappings->{$subfields_group}, $data, $record_document, $altscript);
506
                                $self->_process_mappings($subfields_join_mappings->{$subfields_group}, $data, $record_document, $altscript);
501
                            }
507
                            }
508
                            if ( grep { $_->[0] eq 'match-heading' } @{$subfields_join_mappings->{$subfields_group}} ){
509
                                my $matcher = C4::Heading->new_from_field( $field, undef, 1 ); #new auth heading
510
                                next unless $matcher;
511
                                push @{$record_document->{'match-heading'}}, $matcher->search_form;
512
                                push @{$record_document->{'display_form'}}, $matcher->display_form;
513
                            }
502
                        }
514
                        }
503
                    }
515
                    }
504
                }
516
                }
(-)a/t/db_dependent/Heading.t (-15 / +18 lines)
Lines 27-46 BEGIN { Link Here
27
}
27
}
28
28
29
subtest "MARC21 tests" => sub {
29
subtest "MARC21 tests" => sub {
30
    plan tests => 7;
30
    plan tests => 9;
31
31
32
    t::lib::Mocks::mock_preference('marcflavour', 'MARC21');
32
    t::lib::Mocks::mock_preference('marcflavour', 'MARC21');
33
33
34
    ok(C4::Heading::valid_bib_heading_subfield('100', 'a'), '100a valid');
34
    ok(C4::Heading::valid_heading_subfield('100', 'a'), '100a valid for bib');
35
    ok(!C4::Heading::valid_bib_heading_subfield('100', 'e'), '100e not valid');
35
    ok(!C4::Heading::valid_heading_subfield('100', 'e'), '100e not valid for bib');
36
37
    ok(C4::Heading::valid_heading_subfield('100', 'a', 1), '100a valid for authority');
38
    ok(!C4::Heading::valid_heading_subfield('100', 'e', 1), '100e not valid for authority');
36
39
37
    ok(C4::Heading::valid_bib_heading_subfield('110', 'a'), '110a valid');
40
    ok(C4::Heading::valid_heading_subfield('110', 'a'), '110a valid for bib');
38
    ok(!C4::Heading::valid_bib_heading_subfield('110', 'e'), '110e not valid');
41
    ok(!C4::Heading::valid_heading_subfield('110', 'e'), '110e not valid for bib');
39
42
40
    ok(C4::Heading::valid_bib_heading_subfield('600', 'a'), '600a valid');
43
    ok(C4::Heading::valid_heading_subfield('600', 'a'), '600a valid for bib');
41
    ok(!C4::Heading::valid_bib_heading_subfield('600', 'e'), '600e not valid');
44
    ok(!C4::Heading::valid_heading_subfield('600', 'e'), '600e not valid for bib');
42
45
43
    ok(!C4::Heading::valid_bib_heading_subfield('012', 'a'), '012a invalid field');
46
    ok(!C4::Heading::valid_heading_subfield('012', 'a'), '012a invalid field for bib');
44
};
47
};
45
48
46
subtest "UNIMARC tests" => sub {
49
subtest "UNIMARC tests" => sub {
Lines 48-61 subtest "UNIMARC tests" => sub { Link Here
48
51
49
    t::lib::Mocks::mock_preference('marcflavour', 'UNIMARC');
52
    t::lib::Mocks::mock_preference('marcflavour', 'UNIMARC');
50
53
51
    ok(C4::Heading::valid_bib_heading_subfield('100', 'a'), '100a valid');
54
    ok(C4::Heading::valid_heading_subfield('100', 'a'), '100a valid for bib');
52
    ok(!C4::Heading::valid_bib_heading_subfield('100', 'i'), '100i not valid');
55
    ok(!C4::Heading::valid_heading_subfield('100', 'i'), '100i not valid fir bib');
53
56
54
    ok(C4::Heading::valid_bib_heading_subfield('110', 'a'), '110a valid');
57
    ok(C4::Heading::valid_heading_subfield('110', 'a'), '110a valid for bib');
55
    ok(!C4::Heading::valid_bib_heading_subfield('110', 'i'), '110i not valid');
58
    ok(!C4::Heading::valid_heading_subfield('110', 'i'), '110i not valid for bib');
56
59
57
    ok(C4::Heading::valid_bib_heading_subfield('600', 'a'), '600a valid');
60
    ok(C4::Heading::valid_heading_subfield('600', 'a'), '600a valid for bib');
58
    ok(!C4::Heading::valid_bib_heading_subfield('600', 'i'), '600i not valid');
61
    ok(!C4::Heading::valid_heading_subfield('600', 'i'), '600i not valid for bib');
59
62
60
    ok(!C4::Heading::valid_bib_heading_subfield('012', 'a'), '012a invalid field');
63
    ok(!C4::Heading::valid_heading_subfield('012', 'a'), '012a invalid field for bib');
61
}
64
}
(-)a/t/db_dependent/Heading_MARC21.t (-1 / +1 lines)
Lines 16-22 BEGIN { Link Here
16
SKIP: {
16
SKIP: {
17
    skip "MARC21 heading tests not applicable to UNIMARC", 2 if C4::Context->preference('marcflavour') eq 'UNIMARC';
17
    skip "MARC21 heading tests not applicable to UNIMARC", 2 if C4::Context->preference('marcflavour') eq 'UNIMARC';
18
    my $field = MARC::Field->new( '650', ' ', '0', a => 'Uncles', x => 'Fiction' );
18
    my $field = MARC::Field->new( '650', ' ', '0', a => 'Uncles', x => 'Fiction' );
19
    my $heading = C4::Heading->new_from_bib_field($field);
19
    my $heading = C4::Heading->new_from_field($field);
20
    is($heading->display_form(), 'Uncles--Fiction', 'Display form generation');
20
    is($heading->display_form(), 'Uncles--Fiction', 'Display form generation');
21
    is($heading->search_form(), 'Uncles generalsubdiv Fiction', 'Search form generation');
21
    is($heading->search_form(), 'Uncles generalsubdiv Fiction', 'Search form generation');
22
}
22
}
(-)a/t/db_dependent/Linker_Default.t (-3 / +3 lines)
Lines 50-58 subtest 'Test caching in get_link and update_cache' => sub { Link Here
50
    my $subject_field2 = MARC::Field->new($tags[0],0,2,$tags[1]=>'Science fiction');
50
    my $subject_field2 = MARC::Field->new($tags[0],0,2,$tags[1]=>'Science fiction');
51
    my $genre_field = MARC::Field->new($tags[2],0,2,$tags[3]=>'Science fiction');
51
    my $genre_field = MARC::Field->new($tags[2],0,2,$tags[3]=>'Science fiction');
52
    # Can we build a heading from it?
52
    # Can we build a heading from it?
53
    my $subject_heading = C4::Heading->new_from_bib_field( $subject_field, q{} );
53
    my $subject_heading = C4::Heading->new_from_field( $subject_field, q{} );
54
    my $subject_heading2 = C4::Heading->new_from_bib_field( $subject_field, q{} );
54
    my $subject_heading2 = C4::Heading->new_from_field( $subject_field, q{} );
55
    my $genre_heading = C4::Heading->new_from_bib_field( $genre_field, q{} );
55
    my $genre_heading = C4::Heading->new_from_field( $genre_field, q{} );
56
56
57
57
58
    # Now test to see if C4::Linker can find it.
58
    # Now test to see if C4::Linker can find it.
(-)a/t/db_dependent/Linker_FirstMatch.t (-2 / +1 lines)
Lines 110-116 sub run_tests { Link Here
110
    my $heading;
110
    my $heading;
111
    ok(
111
    ok(
112
        defined(
112
        defined(
113
            $heading = C4::Heading->new_from_bib_field( $new_bibfield, q{} )
113
            $heading = C4::Heading->new_from_field( $new_bibfield, q{} )
114
        ),
114
        ),
115
        'Creating heading from bib field'
115
        'Creating heading from bib field'
116
    );
116
    );
117
- 

Return to bug 24269