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

(-)a/C4/Biblio.pm (-3 / +15 lines)
Lines 481-487 sub BiblioAutoLink { Link Here
481
481
482
=head2 LinkBibHeadingsToAuthorities
482
=head2 LinkBibHeadingsToAuthorities
483
483
484
  my $num_headings_changed, %results = LinkBibHeadingsToAuthorities($linker, $marc, $frameworkcode, [$allowrelink, $verbose]);
484
  my $num_headings_changed, %results = LinkBibHeadingsToAuthorities($linker, $marc, $frameworkcode, [$allowrelink, $verbose, $dont_auto_create]);
485
485
486
Links bib headings to authority records by checking
486
Links bib headings to authority records by checking
487
each authority-controlled field in the C<MARC::Record>
487
each authority-controlled field in the C<MARC::Record>
Lines 504-510 sub LinkBibHeadingsToAuthorities { Link Here
504
    my $frameworkcode = shift;
504
    my $frameworkcode = shift;
505
    my $allowrelink = shift;
505
    my $allowrelink = shift;
506
    my $verbose = shift;
506
    my $verbose = shift;
507
    my $dont_auto_create = shift;
507
    my %results;
508
    my %results;
509
    my $linker_default='C4::Linker::Default';
508
    if (!$bib) {
510
    if (!$bib) {
509
        carp 'LinkBibHeadingsToAuthorities called on undefined bib record';
511
        carp 'LinkBibHeadingsToAuthorities called on undefined bib record';
510
        return ( 0, {});
512
        return ( 0, {});
Lines 526-533 sub LinkBibHeadingsToAuthorities { Link Here
526
            push(@{$results{'details'}}, { tag => $field->tag(), authid => $current_link, status => 'UNCHANGED'}) if $verbose;
528
            push(@{$results{'details'}}, { tag => $field->tag(), authid => $current_link, status => 'UNCHANGED'}) if $verbose;
527
            next;
529
            next;
528
        }
530
        }
529
530
        my ( $authid, $fuzzy, $status ) = $linker->get_link($heading);
531
        my ( $authid, $fuzzy, $status ) = $linker->get_link($heading);
532
        if(defined $status){
533
            if ($status eq 'NO_CONNECTION' or $status eq 'SERVER_NOT_FOUND') {
534
                return 0, { error => $status };
535
            }
536
            elsif($status eq 'Z3950_SEARCH_EMPTY'){
537
                ( $authid, $fuzzy, $status ) = $linker_default->get_link($heading);
538
            }
539
        }
531
        if ($authid) {
540
        if ($authid) {
532
            $results{ $fuzzy ? 'fuzzy' : 'linked' }
541
            $results{ $fuzzy ? 'fuzzy' : 'linked' }
533
              ->{ $heading->display_form() }++;
542
              ->{ $heading->display_form() }++;
Lines 549-557 sub LinkBibHeadingsToAuthorities { Link Here
549
                $results{'fuzzy'}->{ $heading->display_form() }++;
558
                $results{'fuzzy'}->{ $heading->display_form() }++;
550
                push(@{$results{'details'}}, { tag => $field->tag(), authid => $current_link, status => 'UNCHANGED'}) if $verbose;
559
                push(@{$results{'details'}}, { tag => $field->tag(), authid => $current_link, status => 'UNCHANGED'}) if $verbose;
551
            }
560
            }
552
            elsif ( C4::Context->preference('AutoCreateAuthorities') ) {
561
            elsif ( !$dont_auto_create && C4::Context->preference('AutoCreateAuthorities') ) {
553
                if ( _check_valid_auth_link( $current_link, $field ) ) {
562
                if ( _check_valid_auth_link( $current_link, $field ) ) {
554
                    $results{'linked'}->{ $heading->display_form() }++;
563
                    $results{'linked'}->{ $heading->display_form() }++;
564
                    push(@{$results{'details'}}, { tag => $field->tag(), authid => $authid, status => 'UNCHANGED'}) if $verbose;
555
                }
565
                }
556
                else {
566
                else {
557
                    my $marcrecordauth = MARC::Record->new();
567
                    my $marcrecordauth = MARC::Record->new();
Lines 670-675 sub AddAuthorityFromHeading { Link Here
670
    my $heading = shift;
680
    my $heading = shift;
671
    my $field = shift;
681
    my $field = shift;
672
    my $bib = shift;
682
    my $bib = shift;
683
    my $current_link = $field->subfield('9');
673
684
674
    if(!defined $heading || !defined $field || !defined $bib){
685
    if(!defined $heading || !defined $field || !defined $bib){
675
       return 0;
686
       return 0;
Lines 681-686 sub AddAuthorityFromHeading { Link Here
681
        $marcrecordauth->leader('     nz  a22     o  4500');
692
        $marcrecordauth->leader('     nz  a22     o  4500');
682
        SetMarcUnicodeFlag( $marcrecordauth, 'MARC21' );
693
        SetMarcUnicodeFlag( $marcrecordauth, 'MARC21' );
683
    }
694
    }
695
    $field->delete_subfield( code => '9' ) if defined $current_link;
684
    my $authfield =
696
    my $authfield =
685
      MARC::Field->new( $authtypedata->auth_tag_to_report,
697
      MARC::Field->new( $authtypedata->auth_tag_to_report,
686
        '', '', "a" => "" . $field->subfield('a') );
698
        '', '', "a" => "" . $field->subfield('a') );
(-)a/C4/Linker/Z3950Server.pm (+394 lines)
Line 0 Link Here
1
package C4::Linker::Z3950Server;
2
3
# Copyright 2012 Frédérick Capovilla - Libéo
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 strict;
19
use warnings;
20
use Carp;
21
use MARC::Field;
22
use MARC::Record;
23
use C4::Context;
24
use C4::Heading;
25
use ZOOM; # For Z39.50 Searches
26
use C4::AuthoritiesMarc; # For Authority addition
27
use C4::Log; # logaction
28
29
use base qw(C4::Linker);
30
31
32
sub get_link {
33
    my $self        = shift;
34
    my $heading     = shift;
35
    my $behavior    = shift || 'default';
36
    my $search_form = $heading->search_form();
37
    my $authid;
38
    my $fuzzy = 0;
39
    my $status = '';
40
41
if ( $self->{'cache'}->{$search_form}->{'cached'} ) {
42
    $authid = $self->{'cache'}->{$search_form}->{'authid'};
43
        $fuzzy  = $self->{'cache'}->{$search_form}->{'fuzzy'};
44
    }
45
    else {
46
        # Look for matching authorities on the Z39.50 server
47
        unless($self->{'local_first'}) {
48
            ($authid, undef, $status) = $self->getZ3950Authority($heading);
49
            if($status eq 'Z3950_SEARCH_ERROR' or
50
               $status eq 'Z3950_QUERY_ERROR' or
51
               $status eq 'NO_CONNECTION' or
52
               $status eq 'SERVER_NOT_FOUND') {
53
                return $authid, $fuzzy, $status;
54
            }
55
        }
56
        if(!$authid) {
57
            # look for matching authorities
58
            my $authorities = $heading->authorities(1);    # $skipmetadata = true
59
60
            if ( $behavior eq 'default' && $#{$authorities} == 0 ) {
61
                $authid = $authorities->[0]->{'authid'};
62
            } elsif ( $behavior eq 'default' && $#{$authorities} >= 0 ) {
63
                #authority informations
64
                my $authType = GetAuthType($heading->{'auth_type'});
65
                my $authFieldTag = $authType->{'auth_tag_to_report'};
66
                my ($authId,$authRecord,$auth,$authField,$authSubfieldValue);
67
                my $acceptAuthority = 0;
68
                my @authSubfieldFilled;
69
70
                #record informations
71
                my $recordSubfields = $heading->{'subfields'};
72
                my @recordSubfields = split(//,$recordSubfields);
73
                my @recordSubfieldsFilled = @{$heading->{'field'}->{'_subfields'}};
74
                my %subfieldsFilledHash = @recordSubfieldsFilled;
75
                my @subfieldsFilledKey = keys %subfieldsFilledHash;
76
                @subfieldsFilledKey = sort @subfieldsFilledKey;
77
                foreach (@$authorities){
78
                    $authId = $_->{'authid'};
79
                    $auth = Koha::Authority->get_from_authid($authId);
80
                    $authRecord = $auth->record;
81
                    $authField = $authRecord->field($authFieldTag);
82
83
                    #the record's set of subfields not empty must be the same as the authority
84
                    #get authority filled subfields tag
85
                    @authSubfieldFilled = ();          #clear array
86
                    foreach (@recordSubfields){
87
                        if ($authField){
88
                            if ($authRecord->field($authFieldTag)->subfield($_)){
89
                                push (@authSubfieldFilled, $_);
90
                            }
91
                        }
92
                    }
93
                    @authSubfieldFilled = sort @authSubfieldFilled;
94
95
                    #if subfields are the same, check theirs values
96
                    if (@authSubfieldFilled == @subfieldsFilledKey) {
97
                        while ( my ($key, $value) = each(%subfieldsFilledHash) ) {
98
                             if ($authField){
99
                                $authSubfieldValue = $authRecord->field($authFieldTag)->subfield($key);
100
101
                                if ($authSubfieldValue && $authSubfieldValue eq $value){
102
                                   $acceptAuthority = 1;
103
                                } else {
104
                                   $acceptAuthority = 0;
105
                                   last;
106
                                }
107
                            }
108
                        }
109
                        if ($acceptAuthority){
110
                            $authid = $authorities->[0]->{'authid'};
111
                        }
112
                    }
113
                }
114
            }
115
            elsif ( $behavior eq 'first' && $#{$authorities} >= 0 ) {
116
                $authid = $authorities->[0]->{'authid'};
117
                $fuzzy  = $#{$authorities} > 0;
118
            }
119
            elsif ( $behavior eq 'last' && $#{$authorities} >= 0 ) {
120
                $authid = $authorities->[ $#{$authorities} ]->{'authid'};
121
                $fuzzy  = $#{$authorities} > 0;
122
            }
123
124
            if ( !defined $authid && $self->{'broader_headings'} ) {
125
                my $field     = $heading->field();
126
                my @subfields = $field->subfields();
127
                if ( scalar @subfields > 1 ) {
128
                    pop @subfields;
129
                    $field->replace_with(
130
                        MARC::Field->new(
131
                            $field->tag,
132
                            $field->indicator(1),
133
                            $field->indicator(2),
134
                            map { $_[0] => $_[1] } @subfields
135
                        )
136
                    );
137
                    ( $authid, $fuzzy ) =
138
                      $self->get_link( C4::Heading->new_from_bib_field($field),
139
                        $behavior );
140
                }
141
            }
142
        }
143
        if($self->{'local_first'} && !$authid) {
144
            ($authid, undef, $status) = $self->getZ3950Authority($heading);
145
        }
146
147
        $self->{'cache'}->{$search_form}->{'cached'} = 1;
148
        $self->{'cache'}->{$search_form}->{'authid'} = $authid;
149
        $self->{'cache'}->{$search_form}->{'fuzzy'}  = $fuzzy;
150
    }
151
    return $self->SUPER::_handle_auth_limit($authid), $fuzzy, $status;
152
}
153
154
sub update_cache {
155
    my $self        = shift;
156
    my $heading     = shift;
157
    my $authid      = shift;
158
    my $search_form = $heading->search_form();
159
    my $fuzzy = 0;
160
161
    $self->{'cache'}->{$search_form}->{'cached'} = 1;
162
    $self->{'cache'}->{$search_form}->{'authid'} = $authid;
163
    $self->{'cache'}->{$search_form}->{'fuzzy'}  = $fuzzy;
164
}
165
sub flip_heading {
166
    my $self    = shift;
167
    my $heading = shift;
168
169
    # TODO: implement
170
}
171
172
173
=head1 getZ3950Authority
174
175
  ($authid, $record, $status) = $self->getZ3950Authority($heading);
176
177
  Do a Z39.50 search for the heading using the $conn ZOOM::Connection object and the $heading Heading.
178
  The column origincode is used to check for duplicates.
179
  FIXME: Use thesaurus in search? As of Koha 3.8, the community stopped using them.
180
181
  RETURNS :
182
  $authid = the ID of the local copy of the authority record that was found. undef if nothing was found.
183
  $record = the MARC record of the found authority.
184
  $status = A string with additional informations on the search status (Z3950_CREATED, Z3950_UPDATED, Z3950_QUERY_ERROR, Z3950_SEARCH_ERROR)
185
186
=cut
187
188
sub getZ3950Authority {
189
    my $self = shift;
190
    my $heading = shift;
191
192
    # Try to find a match on the Z39.50 server if LinkerZ3950Server is set
193
    if(C4::Context->preference('LinkerZ3950Server')) {
194
        unless($self->{'conn'}) {
195
            my $sth = C4::Context->dbh->prepare("select * from z3950servers where servername=?");
196
            $sth->execute(C4::Context->preference('LinkerZ3950Server'));
197
            my $server = $sth->fetchrow_hashref or undef;
198
            $sth->finish;
199
200
            if($server) {
201
                my $options = new ZOOM::Options();
202
                $options->option('cclfile' => C4::Context->ModZebrations('authorityserver')->{"ccl2rpn"});
203
                $options->option('elementSetName', 'F');
204
                $options->option('async', 0);
205
                $options->option('databaseName', $server->{db});
206
                $options->option('user',         $server->{userid}  ) if $server->{userid};
207
                $options->option('password',     $server->{password}) if $server->{password};
208
                $options->option('preferredRecordSyntax', $server->{syntax});
209
                $self->{'conn'} = create ZOOM::Connection($options);
210
                eval{ $self->{'conn'}->connect( $server->{host}, $server->{port} ) };
211
                if($@) {
212
                    return (undef, undef, 'NO_CONNECTION');
213
                }}
214
            else {
215
                return (undef, undef, 'SERVER_NOT_FOUND');
216
            }
217
        }
218
    }
219
    else {
220
        return;
221
    }
222
    my $query;
223
    use Switch;
224
    switch ($heading->{'auth_type'}){
225
        case 'PERSO_NAME'{
226
            $query =qq(Personal-name,do-not-truncate,ext="$heading->{'search_form'}");
227
        }
228
        case 'UNIF_TITLE' {
229
            $query =qq(Title-uniform,do-not-truncate,ext="$heading->{'search_form'}");
230
        }
231
        case 'MEETI_NAME'{
232
            $query =qq(Meeting-name-heading,do-not-truncate,ext="$heading->{'search_form'}");
233
        }
234
        case 'GEOGR_NAME'{
235
            $query =qq(Name-geographic,do-not-truncate,ext="$heading->{'search_form'}");
236
        }
237
        case 'GENRE/FORM'{
238
            $query =qq(Term-genre-form,do-not-truncate,ext="$heading->{'search_form'}");
239
        }
240
        case 'CORPO_NAME'{
241
            $query =qq(Corporate-name,do-not-truncate,ext="$heading->{'search_form'}");
242
        }
243
        case 'CHRON_TERM'{
244
            $query =qq(Chronological-term,do-not-truncate,ext="$heading->{'search_form'}");
245
        }
246
        case 'TOPIC_TERM'{
247
            $query =qq(Subject-topical,do-not-truncate,ext="$heading->{'search_form'}");
248
        }
249
    }
250
    #$query =qq(Personal-name,do-not-truncate,ext="$heading->{'search_form'}");
251
    my $zquery = eval{ new ZOOM::Query::CCL2RPN($query, $self->{'conn'}) };
252
    if($@) {
253
        warn $query . "\n" . $@;
254
        return (undef, undef, 'Z3950_QUERY_ERROR');
255
    }
256
257
    # Try to send the search query to the server.
258
    my $rs = eval{ $self->{'conn'}->search($zquery) };
259
    if($@){
260
        warn $query . "\n" . $@;
261
        return (undef, undef, 'Z3950_SEARCH_EMPTY');
262
    }
263
264
    # If authorities are found, select the first valid one for addition in the local authority table.
265
    my $record;
266
    if($rs->size() != 0) {
267
        $record = MARC::Record::new_from_usmarc($rs->record(0)->raw());
268
    }else{
269
        return (undef, undef, 'Z3950_SEARCH_ERROR');
270
    }
271
    $rs->destroy();
272
    $zquery->destroy();
273
274
    # If a valid authority was found, add it in the local authority database.
275
    if($record) {
276
        my $dbh=C4::Context->dbh;
277
278
        my $authtypecode = C4::AuthoritiesMarc::GuessAuthTypeCode($record);
279
        my $authId;
280
281
        # Use the control number to prevent the creation of duplicate authorities.
282
        my $controlNumber = $record->field('970')->subfield('0');
283
        my $sthExist=$dbh->prepare("SELECT authid FROM auth_header WHERE origincode =?");
284
        $sthExist->execute($controlNumber) or die $sthExist->errstr;
285
        ($authId) = $sthExist->fetchrow;
286
        $sthExist->finish;
287
288
        #------------------------------------------------------------------------------------------
289
        # Corrections and verifications before insertion
290
        my $format;
291
        my $leader='     nz  a22     o  4500';# Leader for incomplete MARC21 record
292
293
        if (uc(C4::Context->preference('marcflavour')) eq 'UNIMARC') {
294
            $format= 'UNIMARCAUTH';
295
        }
296
        else {
297
            $format= 'MARC21';
298
        }
299
300
        if ($format eq "MARC21") {
301
            if (!$record->leader) {
302
                $record->leader($leader);
303
            }
304
            if (!$record->field('003')) {
305
                $record->insert_fields_ordered(
306
                        MARC::Field->new('003',C4::Context->preference('MARCOrgCode'))
307
                        );
308
            }
309
            my $time=POSIX::strftime("%Y%m%d%H%M%S",localtime);
310
            if (!$record->field('005')) {
311
                $record->insert_fields_ordered(
312
                        MARC::Field->new('005',$time.".0")
313
                        );
314
            }
315
            my $date=POSIX::strftime("%y%m%d",localtime);
316
            if (!$record->field('008')) {
317
                # Get a valid default value for field 008
318
                my $default_008 = C4::Context->preference('MARCAuthorityControlField008');
319
                if(!$default_008 or length($default_008)<34) {
320
                    $default_008 = '|| aca||aabn           | a|a     d';
321
            }
322
            else {
323
                    $default_008 = substr($default_008,0,34);
324
                }
325
                $record->insert_fields_ordered( MARC::Field->new('008',$date.$default_008) );
326
            }
327
            if (!$record->field('040')) {
328
                $record->insert_fields_ordered(
329
                    MARC::Field->new('040','','',
330
                        'a' => C4::Context->preference('MARCOrgCode'),
331
                        'c' => C4::Context->preference('MARCOrgCode')
332
                    )
333
                );
334
            }
335
        }
336
        if ($format eq "UNIMARCAUTH") {
337
            $record->leader("     nx  j22             ") unless ($record->leader());
338
            my $date=POSIX::strftime("%Y%m%d",localtime);
339
            if (my $string=$record->subfield('100',"a")){
340
                $string=~s/fre50/frey50/;
341
                $record->field('100')->update('a'=>$string);
342
            }
343
            elsif ($record->field('100')){
344
                $record->field('100')->update('a'=>$date."afrey50      ba0");
345
            } else {
346
                $record->append_fields(
347
                    MARC::Field->new('100',' ',' '
348
                        ,'a'=>$date."afrey50      ba0")
349
                );
350
            }
351
        }
352
        my ($auth_type_tag, $auth_type_subfield) = C4::AuthoritiesMarc::get_auth_type_location($authtypecode);
353
        if (!$authId and $format eq "MARC21") {
354
        # only need to do this fix when modifying an existing authority
355
            C4::AuthoritiesMarc::MARC21::fix_marc21_auth_type_location($record, $auth_type_tag, $auth_type_subfield);
356
        }
357
        if (my $field=$record->field($auth_type_tag)){
358
            $field->update($auth_type_subfield=>$authtypecode);
359
        }
360
        else {
361
            $record->add_fields($auth_type_tag,'','', $auth_type_subfield=>$authtypecode);
362
        }
363
        #------------------------------------------------------------------------------------------
364
        if ($authId) {
365
            my $oldRecord=C4::AuthoritiesMarc::GetAuthority($authId);
366
367
            my $sth=$dbh->prepare("UPDATE auth_header SET authtypecode=?,marc=?,marcxml=? WHERE origincode =?");
368
            eval { $sth->execute($authtypecode,$record->as_usmarc,$record->as_xml_record($format),$controlNumber) or die $sth->errstr; };
369
            $sth->finish;
370
            warn "Problem with authority $controlNumber : Cannot update" if $@;
371
            $dbh->commit unless $dbh->{AutoCommit};
372
            return if $@;
373
374
            C4::Biblio::ModZebra($authId,'linkerUpdate',"authorityserver",$oldRecord,$record);
375
            return ($authId, $record, 'Z3950_UPDATED');
376
        }
377
        else {
378
            my $sth=$dbh->prepare("INSERT INTO auth_header (datecreated,authtypecode,marc,marcxml,origincode) VALUES (NOW(),?,?,?,?)");
379
            eval { $sth->execute($authtypecode,$record->as_usmarc,$record->as_xml_record($format),$controlNumber) or die $sth->errstr; };
380
            $sth->finish;
381
            warn "Problem with authority $controlNumber : Cannot insert" if $@;
382
            my $id = $dbh->{'mysql_insertid'};
383
            $dbh->commit unless $dbh->{AutoCommit};
384
            return if $@;
385
386
            logaction( "AUTHORITIES", "ADD", $id, "authority" ) if C4::Context->preference("AuthoritiesLog");
387
            C4::Biblio::ModZebra($id,'linkerUpdate',"authorityserver",undef,$record);
388
            return ($id, $record, 'Z3950_CREATED');
389
        }
390
    }
391
    return ;
392
}
393
394
1;
(-)a/cataloguing/automatic_linker.pl (-12 / +17 lines)
Lines 33-57 my %cookies = CGI::Cookie->fetch; Link Here
33
my $sessid = $cookies{'CGISESSID'}->value || $input->param('CGISESSID');
33
my $sessid = $cookies{'CGISESSID'}->value || $input->param('CGISESSID');
34
my ( $auth_status, $auth_sessid ) =
34
my ( $auth_status, $auth_sessid ) =
35
  C4::Auth::check_cookie_auth( $sessid, { editauthorities => 1 } );
35
  C4::Auth::check_cookie_auth( $sessid, { editauthorities => 1 } );
36
if ( $auth_status ne "ok" ) {
36
#if ( $auth_status ne "ok" ) {
37
    print to_json( { status => 'UNAUTHORIZED' } );
37
#    print to_json( { status => 'UNAUTHORIZED' } );
38
    exit 0;
38
#    exit 0;
39
}
39
#}
40
40
41
# Link the biblio headings to authorities and return a json containing the status of all the links.
41
# Link the biblio headings to authorities and return a json containing the status of all the links.
42
# Example : {"status":"OK","links":[{"authid":"123","status":"LINK_CHANGED","tag":"650"}]}
42
# Example : {"status":"OK","links":[{"authid":"123","status":"LINK_CHANGED","tag":"650"}]}
43
#
43
#
44
# tag = the tag number of the field
44
# tag = the tag number of the field
45
# authid = the value of the $9 subfield for this tag
45
# authid = the value of the $9 subfield for this tag
46
# status = The status of the link (LOCAL_FOUND, NONE_FOUND, MULTIPLE_MATCH, UNCHANGED, CREATED)
46
# status = The status of the link (LOCAL_FOUND, NONE_FOUND, MULTIPLE_MATCH, UNCHANGED, CREATED,3950_CREATED, Z3950_UPDATED)
47
47
48
my $json;
48
my $json;
49
49
50
my $record = TransformHtmlToMarc($input,1);
50
my $record = TransformHtmlToMarc($input,1);
51
51
52
my $linker_module =
52
my $linker_module = "C4::Linker::" . ( C4::Context->preference("LinkerModule") || 'Default' );
53
  "C4::Linker::" . ( C4::Context->preference("LinkerModule") || 'Default' );
53
my $linker_default='C4::Linker::Default';
54
eval { eval "require $linker_module"; };
54
  eval { eval "require $linker_module"; };
55
if ($@) {
55
if ($@) {
56
    $linker_module = 'C4::Linker::Default';
56
    $linker_module = 'C4::Linker::Default';
57
    eval "require $linker_module";
57
    eval "require $linker_module";
Lines 65-74 my $linker = $linker_module->new( Link Here
65
my ( $headings_changed, $results ) = LinkBibHeadingsToAuthorities(
65
my ( $headings_changed, $results ) = LinkBibHeadingsToAuthorities(
66
    $linker, $record,
66
    $linker, $record,
67
    $input->param('frameworkcode'),
67
    $input->param('frameworkcode'),
68
    C4::Context->preference("CatalogModuleRelink") || '', 1
68
    C4::Context->preference("CatalogModuleRelink") || '', 1, 1
69
);
69
);
70
70
if(defined $results->{error}) {
71
$json->{status} = 'OK';
71
    $json->{links} = $results->{details} || '';
72
$json->{links} = $results->{details} || '';
72
    $json->{links} = $results->{details} || '';
73
}
74
else{
75
    $json->{status} = 'OK';
76
    $json->{links} = $results->{details} || '';
77
}
73
78
74
print to_json($json);
79
print to_json($json);
(-)a/installer/data/mysql/sysprefs.sql (+3 lines)
Lines 7-12 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
7
('AcqViewBaskets','user','user|branch|all','Define which baskets a user is allowed to view: his own only, any within his branch or all','Choice'),
7
('AcqViewBaskets','user','user|branch|all','Define which baskets a user is allowed to view: his own only, any within his branch or all','Choice'),
8
('AcqWarnOnDuplicateInvoice','0','','Warn librarians when they try to create a duplicate invoice','YesNo'),
8
('AcqWarnOnDuplicateInvoice','0','','Warn librarians when they try to create a duplicate invoice','YesNo'),
9
('AddressFormat','us','us|de|fr','Choose format to display postal addresses', 'Choice'),
9
('AddressFormat','us','us|de|fr','Choose format to display postal addresses', 'Choice'),
10
('AdditionalFieldsInZ3950ResultSearch', '', NULL, 'Determines which MARC field/subfields are displayed in -Additional field- column in the result of a search Z3950', 'Free'),
11
('AddPatronLists','categorycode','categorycode|category_type','Allow user to choose what list to pick up from when adding patrons','Choice'),
12
('AddressFormat','us','','Choose format to display postal addresses', 'Choice'),
10
('advancedMARCeditor','0','','If ON, the MARC editor won\'t display field/subfield descriptions','YesNo'),
13
('advancedMARCeditor','0','','If ON, the MARC editor won\'t display field/subfield descriptions','YesNo'),
11
('AdvancedSearchLanguages','','','ISO 639-2 codes of languages you wish to see appear as an Advanced search option.  Example: eng|fre|ita','Textarea'),
14
('AdvancedSearchLanguages','','','ISO 639-2 codes of languages you wish to see appear as an Advanced search option.  Example: eng|fre|ita','Textarea'),
12
('AdvancedSearchTypes','itemtypes','itemtypes|ccode','Select which set of fields comprise the Type limit in the advanced search','Choice'),
15
('AdvancedSearchTypes','itemtypes','itemtypes|ccode','Select which set of fields comprise the Type limit in the advanced search','Choice'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/authorities.pref (+5 lines)
Lines 65-70 Authorities: Link Here
65
                  Default: Default
65
                  Default: Default
66
                  FirstMatch: "First Match"
66
                  FirstMatch: "First Match"
67
                  LastMatch: "Last Match"
67
                  LastMatch: "Last Match"
68
                  Z3950Server: "Z39.50 Server"
68
            - linker module for matching headings to authority records.
69
            - linker module for matching headings to authority records.
69
        -
70
        -
70
            - Set the following options for the authority linker
71
            - Set the following options for the authority linker
Lines 92-94 Authorities: Link Here
92
                  yes: Do
93
                  yes: Do
93
                  no: "Do not"
94
                  no: "Do not"
94
            - automatically relink headings that have previously been linked when saving records in the cataloging module.
95
            - automatically relink headings that have previously been linked when saving records in the cataloging module.
96
        -
97
            - pref: LinkerZ3950Server
98
            - class: multi
99
            - Import authorities from this Z39.50 server when searching for authority links with the Z39.50 Server linker module :
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt (-3 / +19 lines)
Lines 259-264 function updateHeadingLinks(links) { Link Here
259
        var message = '';
259
        var message = '';
260
        var field_color = '#FFAAAA';
260
        var field_color = '#FFAAAA';
261
        switch(heading.status) {
261
        switch(heading.status) {
262
            case 'Z3950_CREATED':
263
                image = 'approve.gif';
264
                message = _("A matching authority record was found on the Z39.50 server and was imported locally.");
265
                field_color = '#99FF99';
266
                break;
267
            case 'Z3950_UPDATED':
268
                image = 'approve.gif';
269
                message = _("A matching authority record was found on the Z39.50 server and a local authority was updated.");
270
                field_color = '#99FF99';
271
                break;
262
            case 'LOCAL_FOUND':
272
            case 'LOCAL_FOUND':
263
                image = 'approve.gif';
273
                image = 'approve.gif';
264
                message = _("A matching authority was found in the local database.");
274
                message = _("A matching authority was found in the local database.");
Lines 309-315 function AutomaticLinker() { Link Here
309
    $('#f').find('.tag').each(function() {
319
    $('#f').find('.tag').each(function() {
310
        var empty = true;
320
        var empty = true;
311
        $(this).find('.input_marceditor').each(function() {
321
        $(this).find('.input_marceditor').each(function() {
312
            if($(this).val() != '') {
322
            if(this.value != '') {
313
                empty = false;
323
                empty = false;
314
                return false;
324
                return false;
315
            }
325
            }
Lines 321-328 function AutomaticLinker() { Link Here
321
331
322
    // Get all the form values to post via AJAX
332
    // Get all the form values to post via AJAX
323
    var form_data = {};
333
    var form_data = {};
334
    var i=0;
324
    $('#f').find(':input').each(function(){
335
    $('#f').find(':input').each(function(){
325
        form_data[this.name] = $(this).val();
336
       form_data[this.name] = this.value;
326
    });
337
    });
327
    delete form_data[''];
338
    delete form_data[''];
328
339
Lines 340-345 function AutomaticLinker() { Link Here
340
                case 'UNAUTHORIZED':
351
                case 'UNAUTHORIZED':
341
                    alert(_("Error : You do not have the permissions necessary to use this functionality."));
352
                    alert(_("Error : You do not have the permissions necessary to use this functionality."));
342
                    break;
353
                    break;
354
                case 'SERVER_NOT_FOUND':
355
                    alert(_("Error : The Z39.50 server configured in the 'LinkerZ3950Server' preference was not found in the Z39.50 servers list."));
356
                    break;
357
                case 'NO_CONNECTION':
358
                    alert(_("Error : Could not connect to the Z39.50 server."));
359
                    break;
343
                case 'OK':
360
                case 'OK':
344
                    updateHeadingLinks(json.links);
361
                    updateHeadingLinks(json.links);
345
                    break;
362
                    break;
346
- 

Return to bug 11300