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

(-)a/C4/Biblio.pm (-6 / +19 lines)
Lines 435-440 Returns the number of headings changed Link Here
435
sub BiblioAutoLink {
435
sub BiblioAutoLink {
436
    my $record        = shift;
436
    my $record        = shift;
437
    my $frameworkcode = shift;
437
    my $frameworkcode = shift;
438
    my $verbose = shift;
438
    if (!$record) {
439
    if (!$record) {
439
        carp('Undefined record passed to BiblioAutoLink');
440
        carp('Undefined record passed to BiblioAutoLink');
440
        return 0;
441
        return 0;
Lines 452-466 sub BiblioAutoLink { Link Here
452
453
453
    my $linker = $linker_module->new(
454
    my $linker = $linker_module->new(
454
        { 'options' => C4::Context->preference("LinkerOptions") } );
455
        { 'options' => C4::Context->preference("LinkerOptions") } );
455
    my ( $headings_changed, undef ) =
456
    my ( $headings_changed, $results ) =
456
      LinkBibHeadingsToAuthorities( $linker, $record, $frameworkcode, C4::Context->preference("CatalogModuleRelink") || '' );
457
      LinkBibHeadingsToAuthorities( $linker, $record, $frameworkcode, C4::Context->preference("CatalogModuleRelink") || '', $verbose );
457
    # By default we probably don't want to relink things when cataloging
458
    # By default we probably don't want to relink things when cataloging
458
    return $headings_changed;
459
    return $headings_changed, $results;
459
}
460
}
460
461
461
=head2 LinkBibHeadingsToAuthorities
462
=head2 LinkBibHeadingsToAuthorities
462
463
463
  my $num_headings_changed, %results = LinkBibHeadingsToAuthorities($linker, $marc, $frameworkcode, [$allowrelink]);
464
  my $num_headings_changed, %results = LinkBibHeadingsToAuthorities($linker, $marc, $frameworkcode, [$allowrelink, $verbose]);
464
465
465
Links bib headings to authority records by checking
466
Links bib headings to authority records by checking
466
each authority-controlled field in the C<MARC::Record>
467
each authority-controlled field in the C<MARC::Record>
Lines 482-487 sub LinkBibHeadingsToAuthorities { Link Here
482
    my $bib           = shift;
483
    my $bib           = shift;
483
    my $frameworkcode = shift;
484
    my $frameworkcode = shift;
484
    my $allowrelink = shift;
485
    my $allowrelink = shift;
486
    my $verbose = shift;
485
    my %results;
487
    my %results;
486
    if (!$bib) {
488
    if (!$bib) {
487
        carp 'LinkBibHeadingsToAuthorities called on undefined bib record';
489
        carp 'LinkBibHeadingsToAuthorities called on undefined bib record';
Lines 489-495 sub LinkBibHeadingsToAuthorities { Link Here
489
    }
491
    }
490
    require C4::Heading;
492
    require C4::Heading;
491
    require C4::AuthoritiesMarc;
493
    require C4::AuthoritiesMarc;
492
493
    $allowrelink = 1 unless defined $allowrelink;
494
    $allowrelink = 1 unless defined $allowrelink;
494
    my $num_headings_changed = 0;
495
    my $num_headings_changed = 0;
495
    foreach my $field ( $bib->fields() ) {
496
    foreach my $field ( $bib->fields() ) {
Lines 502-507 sub LinkBibHeadingsToAuthorities { Link Here
502
        if ( defined $current_link && (!$allowrelink || !C4::Context->preference('LinkerRelink')) )
503
        if ( defined $current_link && (!$allowrelink || !C4::Context->preference('LinkerRelink')) )
503
        {
504
        {
504
            $results{'linked'}->{ $heading->display_form() }++;
505
            $results{'linked'}->{ $heading->display_form() }++;
506
            push(@{$results{'details'}}, { tag => $field->tag(), authid => $current_link, status => 'UNCHANGED'}) if $verbose;
505
            next;
507
            next;
506
        }
508
        }
507
509
Lines 509-525 sub LinkBibHeadingsToAuthorities { Link Here
509
        if ($authid) {
511
        if ($authid) {
510
            $results{ $fuzzy ? 'fuzzy' : 'linked' }
512
            $results{ $fuzzy ? 'fuzzy' : 'linked' }
511
              ->{ $heading->display_form() }++;
513
              ->{ $heading->display_form() }++;
512
            next if defined $current_link and $current_link == $authid;
514
            if(defined $current_link and $current_link == $authid) {
515
                push(@{$results{'details'}}, { tag => $field->tag(), authid => $current_link, status => 'UNCHANGED'}) if $verbose;
516
                next;
517
            }
513
518
514
            $field->delete_subfield( code => '9' ) if defined $current_link;
519
            $field->delete_subfield( code => '9' ) if defined $current_link;
515
            $field->add_subfields( '9', $authid );
520
            $field->add_subfields( '9', $authid );
516
            $num_headings_changed++;
521
            $num_headings_changed++;
522
            push(@{$results{'details'}}, { tag => $field->tag(), authid => $authid, status => 'LOCAL_FOUND'}) if $verbose;
517
        }
523
        }
518
        else {
524
        else {
525
            my $authority_type = Koha::Authority::Types->find( $heading->auth_type() );
519
            if ( defined $current_link
526
            if ( defined $current_link
520
                && (!$allowrelink || C4::Context->preference('LinkerKeepStale')) )
527
                && (!$allowrelink || C4::Context->preference('LinkerKeepStale')) )
521
            {
528
            {
522
                $results{'fuzzy'}->{ $heading->display_form() }++;
529
                $results{'fuzzy'}->{ $heading->display_form() }++;
530
                push(@{$results{'details'}}, { tag => $field->tag(), authid => $current_link, status => 'UNCHANGED'}) if $verbose;
523
            }
531
            }
524
            elsif ( C4::Context->preference('AutoCreateAuthorities') ) {
532
            elsif ( C4::Context->preference('AutoCreateAuthorities') ) {
525
                if ( _check_valid_auth_link( $current_link, $field ) ) {
533
                if ( _check_valid_auth_link( $current_link, $field ) ) {
Lines 595-618 sub LinkBibHeadingsToAuthorities { Link Here
595
                    $num_headings_changed++;
603
                    $num_headings_changed++;
596
                    $linker->update_cache($heading, $authid);
604
                    $linker->update_cache($heading, $authid);
597
                    $results{'added'}->{ $heading->display_form() }++;
605
                    $results{'added'}->{ $heading->display_form() }++;
606
                    push(@{$results{'details'}}, { tag => $field->tag(), authid => $authid, status => 'CREATED'}) if $verbose;
598
                }
607
                }
599
            }
608
            }
600
            elsif ( defined $current_link ) {
609
            elsif ( defined $current_link ) {
601
                if ( _check_valid_auth_link( $current_link, $field ) ) {
610
                if ( _check_valid_auth_link( $current_link, $field ) ) {
602
                    $results{'linked'}->{ $heading->display_form() }++;
611
                    $results{'linked'}->{ $heading->display_form() }++;
612
                    push(@{$results{'details'}}, { tag => $field->tag(), authid => $authid, status => 'UNCHANGED'}) if $verbose;
603
                }
613
                }
604
                else {
614
                else {
605
                    $field->delete_subfield( code => '9' );
615
                    $field->delete_subfield( code => '9' );
606
                    $num_headings_changed++;
616
                    $num_headings_changed++;
607
                    $results{'unlinked'}->{ $heading->display_form() }++;
617
                    $results{'unlinked'}->{ $heading->display_form() }++;
618
                    push(@{$results{'details'}}, { tag => $field->tag(), authid => undef, status => 'NONE_FOUND', auth_type => $heading->auth_type(), tag_to_report => $authority_type->auth_tag_to_report}) if $verbose;
608
                }
619
                }
609
            }
620
            }
610
            else {
621
            else {
611
                $results{'unlinked'}->{ $heading->display_form() }++;
622
                $results{'unlinked'}->{ $heading->display_form() }++;
623
                push(@{$results{'details'}}, { tag => $field->tag(), authid => undef, status => 'NONE_FOUND', auth_type => $heading->auth_type(), tag_to_report => $authority_type->auth_tag_to_report}) if $verbose;
612
            }
624
            }
613
        }
625
        }
614
626
615
    }
627
    }
628
    push(@{$results{'details'}}, { tag => '', authid => undef, status => 'UNCHANGED'}) unless %results;
616
    return $num_headings_changed, \%results;
629
    return $num_headings_changed, \%results;
617
}
630
}
618
631
(-)a/authorities/authorities.pl (-1 / +4 lines)
Lines 289-294 sub create_input { Link Here
289
289
290
        }
290
        }
291
    }
291
    }
292
    if ($cgi->param('tagreport') && $subfield_data{tag} == $cgi->param('tagreport')) {
293
        $subfield_data{marc_value}{value} = $cgi->param('tag'. $cgi->param('tagbiblio') . 'subfield' . $subfield_data{subfield});
294
    }
292
    $subfield_data{'index_subfield'} = $index_subfield;
295
    $subfield_data{'index_subfield'} = $index_subfield;
293
    return \%subfield_data;
296
    return \%subfield_data;
294
}
297
}
Lines 576-582 my ($template, $loggedinuser, $cookie) Link Here
576
                            flagsrequired => {editauthorities => 1},
579
                            flagsrequired => {editauthorities => 1},
577
                            debug => 1,
580
                            debug => 1,
578
                            });
581
                            });
579
$template->param(nonav   => $nonav,index=>$myindex,authtypecode=>$authtypecode,breedingid=>$breedingid,);
582
$template->param(nonav   => $nonav,index=>$myindex,authtypecode=>$authtypecode,breedingid=>$breedingid);
580
583
581
$tagslib = GetTagsLabels(1,$authtypecode);
584
$tagslib = GetTagsLabels(1,$authtypecode);
582
$mandatory_z3950 = GetMandatoryFieldZ3950($authtypecode);
585
$mandatory_z3950 = GetMandatoryFieldZ3950($authtypecode);
(-)a/cataloguing/z3950_auth_search.pl (+3 lines)
Lines 42-47 my $subjectsubdiv = $input->param('subjectsubdiv'); Link Here
42
my $srchany       = $input->param('srchany');
42
my $srchany       = $input->param('srchany');
43
my $op            = $input->param('op')||'';
43
my $op            = $input->param('op')||'';
44
my $page            = $input->param('current_page') || 1;
44
my $page            = $input->param('current_page') || 1;
45
my $index =$input->param('index');
45
$page = $input->param('goto_page') if $input->param('changepage_goto');
46
$page = $input->param('goto_page') if $input->param('changepage_goto');
46
my $controlnumber    = $input->param('controlnumber');
47
my $controlnumber    = $input->param('controlnumber');
47
48
Lines 65-70 $template->param( Link Here
65
    srchany      => $srchany,
66
    srchany      => $srchany,
66
    authid => $authid,
67
    authid => $authid,
67
    controlnumber => $controlnumber,
68
    controlnumber => $controlnumber,
69
    index => $index,
68
);
70
);
69
71
70
if ( $op ne "do_search" ) {
72
if ( $op ne "do_search" ) {
Lines 74-79 if ( $op ne "do_search" ) { Link Here
74
    $template->param(
76
    $template->param(
75
        serverloop   => $serverloop,
77
        serverloop   => $serverloop,
76
        opsearch     => "search",
78
        opsearch     => "search",
79
        index        => $index,
77
    );
80
    );
78
    output_html_with_http_headers $input, $cookie, $template->output;
81
    output_html_with_http_headers $input, $cookie, $template->output;
79
    exit;
82
    exit;
(-)a/koha-tmpl/intranet-tmpl/prog/css/addbiblio.css (+16 lines)
Lines 322-327 tbody tr.active td { Link Here
322
    display: inline-block;
322
    display: inline-block;
323
}
323
}
324
324
325
.matching_authority{
326
    color: #99FF99;
327
}
328
329
.no_matching_authority{
330
    color: #FFAAAA;
331
}
332
333
.matching_authority_field{
334
     background-color: #99FF99 !important;
335
 }
336
337
 .no_matching_authority_field{
338
     background-color: #FFAAAA !important;
339
 }
340
325
@media (min-width: 768px) {
341
@media (min-width: 768px) {
326
    li.subfield_line label {
342
    li.subfield_line label {
327
        width: 20em;
343
        width: 20em;
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/authorities.tt (-3 / +4 lines)
Lines 32-39 Link Here
32
		});
32
		});
33
        $("#z3950submit").click(function(){
33
        $("#z3950submit").click(function(){
34
            var strQuery = GetZ3950Terms();
34
            var strQuery = GetZ3950Terms();
35
            var index = "&index=[% index | html %]";
35
            if(strQuery){
36
            if(strQuery){
36
                window.open("/cgi-bin/koha/cataloguing/z3950_auth_search.pl?authid=[% authid | html %]"+strQuery,"z3950search",'width=740,height=450,location=yes,toolbar=no,scrollbars=yes,resize=yes');
37
                window.open("/cgi-bin/koha/cataloguing/z3950_auth_search.pl?authid=[% authid | html %]"+strQuery+index,"z3950search",'width=740,height=450,location=yes,toolbar=no,scrollbars=yes,resize=yes');
37
            }
38
            }
38
            return false;
39
            return false;
39
        });
40
        });
Lines 211-219 function confirmnotdup(redirect){ Link Here
211
    <input type="hidden" name="op" value="add" />
212
    <input type="hidden" name="op" value="add" />
212
    <input type="hidden" name="addfield_field" value="" />
213
    <input type="hidden" name="addfield_field" value="" />
213
    <input type="hidden" name="repeat_field" value="" />
214
    <input type="hidden" name="repeat_field" value="" />
214
    <input type="hidden" name="authtypecode" value="[% authtypecode | html %]" />
215
    <input type="hidden" name="authtypecode" value="[% authtypecode  | html%]" />
215
    <input type="hidden" name="authid" value="[% authid | html %]" />
216
    <input type="hidden" name="authid" value="[% authid | html %]" />
216
    <input type="hidden" name="index" value="[% index | html %]" />
217
    <input type="hidden" name="index" value="[% index | html  %]" />
217
    <input type="hidden" value="0" id="confirm_not_duplicate" name="confirm_not_duplicate" />
218
    <input type="hidden" value="0" id="confirm_not_duplicate" name="confirm_not_duplicate" />
218
219
219
    <div id="toolbar" class="btn-toolbar">
220
    <div id="toolbar" class="btn-toolbar">
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/blinddetail-biblio-search.tt (-2 / +19 lines)
Lines 44-54 Link Here
44
            var whichfield;
44
            var whichfield;
45
            try {
45
            try {
46
                whichfield = opener.opener.document.getElementById(index_start);
46
                whichfield = opener.opener.document.getElementById(index_start);
47
                autolinker_dialog = opener.opener.document.getElementById("autolinker_dialog");
47
            } catch(e) {
48
            } catch(e) {
48
                return;
49
                whichfield = opener.document.getElementById(index_start);
50
                autolinker_dialog = opener.document.getElementById("autolinker_dialog");
49
            }
51
            }
50
            var field_start = whichfield.parentNode.parentNode.parentNode;
52
            var field_start = whichfield.parentNode.parentNode.parentNode;
51
52
            // Sets the good number of form fields for the specified subfield
53
            // Sets the good number of form fields for the specified subfield
53
            // Returns false if the cloning failed
54
            // Returns false if the cloning failed
54
            function SetSubfieldNumber(subfield_name, nb) {
55
            function SetSubfieldNumber(subfield_name, nb) {
Lines 138-143 Link Here
138
                [% ELSE %]
139
                [% ELSE %]
139
                    if(code.value=='9'){
140
                    if(code.value=='9'){
140
                        subfield.value = "[% To.json(authid) | $raw %]";
141
                        subfield.value = "[% To.json(authid) | $raw %]";
142
                        subfield.className = subfield.className.replace("no_matching_authority_field", "matching_authority_field");
143
141
                        break;
144
                        break;
142
                    }
145
                    }
143
                [% END %]
146
                [% END %]
Lines 145-150 Link Here
145
            }
148
            }
146
            [% END %]
149
            [% END %]
147
150
151
            //Delete create authority button and status
152
            var linkinfos = field_start.getElementsByTagName('i');
153
            for (index = linkinfos.length - 1; index >= 0; index--) {
154
                linkinfos[index].parentNode.removeChild(linkinfos[index]);
155
            }
156
            //Change message autolinker_dialog
157
            var subfield_dialog = $(autolinker_dialog).children('ul').children('li');
158
            for (index = subfield_dialog.length - 1; index >= 0; index--){
159
                var tag_field = field_start.id.split("_")[1];
160
                if (subfield_dialog[index].innerHTML.indexOf(tag_field) !== -1 ){
161
                    subfield_dialog[index].innerHTML = subfield_dialog[index].innerHTML.replace(_("No matching authority found."), _("No matching authority found. A new authority was created or imported"));
162
                    break;
163
                }
164
            }
148
            opener.close();
165
            opener.close();
149
            window.close();
166
            window.close();
150
            return false;
167
            return false;
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt (-1 / +240 lines)
Lines 90-95 Link Here
90
            PopupZ3950();
90
            PopupZ3950();
91
        });
91
        });
92
92
93
        $("#linkerbutton").click(function(){
94
            AutomaticLinker();
95
        });
96
93
        $("#saverecord").click(function(){
97
        $("#saverecord").click(function(){
94
            $(".btn-group").removeClass("open");
98
            $(".btn-group").removeClass("open");
95
            onOption();
99
            onOption();
Lines 176-183 Link Here
176
        var onOption = function () {
180
        var onOption = function () {
177
            return Check();
181
            return Check();
178
        }
182
        }
179
    [% END %]
183
[% END %]
184
185
function confirmnotdup(redirect){
186
    $("#confirm_not_duplicate").attr("value","1");
187
    $("#redirect").attr("value",redirect);
188
    Check();
189
}
190
191
function Dopop(link,i) {
192
    defaultvalue = document.getElementById(i).value;
193
    window.open(link+"&result="+defaultvalue,"valuebuilder",'width=700,height=550,toolbar=false,scrollbars=yes');
194
}
195
196
/**
197
 * this function open a popup to search on z3950 server.
198
 */
199
function PopupZ3950() {
200
    var strQuery = GetZ3950Terms();
201
    if(strQuery){
202
        window.open("/cgi-bin/koha/cataloguing/z3950_search.pl?biblionumber=[% biblionumber | html %]"+strQuery,"z3950search",'width=740,height=450,location=yes,toolbar=no,scrollbars=yes,resize=yes');
203
    }
204
}
205
206
/**
207
* this function append button for create new authority if not found
208
*/
209
210
function addCreateAuthorityButton(tag_subfield_line, heading, tag_index) {
211
    var title = _("Create authority");
212
    var elem = $('<a href="#" title="' + title + '"><i class="fa fa-plus-circle"></i></a>');
213
    tag_subfield_line.append(elem);
214
    var tag_subfield_line_a = $('.subfield_line[id^=subfield' + heading.tag + 'a]').eq(tag_index);
215
    var subfield_a = tag_subfield_line_a.children('.input_marceditor').eq(0);
216
    var index = subfield_a.attr('id');
217
    elem.click(function() {
218
        var popup = window.open("", "new_auth_popup",'fullscreen,toolbar=false,scrollbars=yes');
219
        if(popup !== null) {
220
            // Create a new form that will be POSTed in the new window
221
            var form = $('<form>').attr({
222
            method: 'post',
223
            action: "../authorities/authorities.pl",
224
            target: "new_auth_popup"
225
            });
226
            //add the authtypecode
227
            form.append($('<input>').attr({
228
                type: 'hidden',
229
                name: 'authtypecode',
230
                value: heading.auth_type
231
            }));
232
            form.append($('<input>').attr({
233
                type: 'hidden',
234
                name: 'tagreport',
235
                value: heading.tag_to_report
236
            }));
237
            form.append($('<input>').attr({
238
                type: 'hidden',
239
                name: 'tagbiblio',
240
                value: heading.tag
241
            }));
242
            form.append($('<input>').attr({
243
                type: 'hidden',
244
                name: 'index',
245
                value: index
246
            }));
247
            $('.tag[id^=tag_' + heading.tag + '_]').eq(tag_index).find(':input').each(function(){
248
                form.append($('<input>').attr({
249
                    type: 'hidden',
250
                    name: this.name.split('_',4).join(''),
251
                    value: $(this).val()
252
                }));
253
            });
254
255
            $('body').append(form);
256
            form.submit();
257
            form.remove();
258
        }
259
        return false;
260
    });
261
262
}
263
264
/**
265
 * Updates the authid for every heading field
266
 * Adds visual feedback for the changes made on the form.
267
 */
268
function updateHeadingLinks(links) {
269
    var current_tag = '';
270
    var tag_index = 0;
271
272
    // Delete the old message dialog and create a new one
273
    $('#autolinker_dialog').remove();
274
    var message_dialog = $('<div id="autolinker_dialog" class="dialog"><strong>' + _("Automatic authority link results:") + '</strong><ul></ul></div>');
275
    var message_dialog_ul = message_dialog.find('ul');
276
277
    $.each(links, function(index, heading) {
278
        if(current_tag == heading.tag) {
279
            tag_index++;
280
        }
281
        else {
282
            current_tag = heading.tag;
283
            tag_index = 0;
284
        }
285
286
        // Find the $9 field to update
287
        var tag_subfield_line = $('.subfield_line[id^=subfield' + heading.tag + '9]').eq(tag_index);
288
        var subfield = tag_subfield_line.children('.input_marceditor').eq(0);
289
290
        // Delete the old status if one exists
291
        tag_subfield_line.children('.subfield_status').remove();
292
293
        // If the field wasn't modified. Skip it.
294
        if(heading.status == 'UNCHANGED') {
295
            return;
296
        }
297
298
299
        // Make the subfield line visible and update its value
300
        tag_subfield_line.show();
301
        subfield.val(heading.authid);
302
303
        // Add the new status
304
        var image = '<i class="fa fa-close no_matching_authority" </i> ';
305
        var message = '';
306
        var field_class = 'no_matching_authority_field';
307
        switch(heading.status) {
308
            case 'LOCAL_FOUND':
309
                image = '<i class="fa fa-check matching_authority"</i> ';
310
                message = _("A matching authority was found in the local database.");
311
                field_class = 'matching_authority_field';
312
                break;
313
            case 'CREATED':
314
                image = '<i class="fa fa-check matching_authority"></i> ';
315
                message = _("No matching authority found. A new authority was created automatically.");
316
                field_class = 'matching_authority_field';
317
                break;
318
            case 'MULTIPLE_MATCH':
319
                message = _("More than one local match found. Possibly a duplicate authority!");
320
                break;
321
            case 'NONE_FOUND':
322
                message = _("No matching authority found.");
323
                break;
324
            default:
325
                message = heading.status;
326
                break;
327
        }
180
328
329
        subfield[0].classList.add(field_class);
330
        tag_subfield_line.find('i').each(function() {
331
            this.remove();
332
        });
333
        tag_subfield_line.append(image);
334
335
        // Add the message to the dialog
336
        message_dialog_ul.append('<li><strong>' + heading.tag + '</strong> - ' + message + '</li>');
337
338
        // Add a link to create a new authority if none was found
339
        if(heading.status == 'NONE_FOUND' && tag_subfield_line.find('i').length == 1) {
340
            addCreateAuthorityButton(tag_subfield_line, heading , tag_index);
341
        }
342
    });
343
344
    if(message_dialog.find('li').length == 0) {
345
        message_dialog_ul.append("<li>" + _("No authority link was changed.") + "</li>");
346
    }
347
    $('#addbibliotabs').before(message_dialog);
348
}
349
350
/**
351
 * Use an ajax request to automatically find authority links for the current record
352
 */
353
function AutomaticLinker() {
354
    // Show the Loading overlay
355
    $("#loading").show();
356
357
    // Remove fields that are completely empty
358
    $('#f').find('.tag').each(function() {
359
        var empty = true;
360
        $(this).find('.input_marceditor').each(function() {
361
            if($(this).val() != '') {
362
                empty = false;
363
                return false;
364
            }
365
        });
366
        if(empty) {
367
            UnCloneField($(this).attr('id'));
368
        }
369
    });
370
371
    // Get all the form values to post via AJAX
372
    var form_data = {};
373
    $('#f').find(':input').each(function(){
374
        form_data[this.name] = $(this).val();
375
    });
376
    delete form_data[''];
377
378
    // Send the data to automatic_linker.pl
379
    $.ajax({
380
        url:'/cgi-bin/koha/svc/cataloguing/automatic_linker.pl',
381
        type:'post',
382
        data: form_data,
383
        dataType: 'json',
384
        error: function(xhr) {
385
            alert("Error : \n" + xhr.responseText);
386
        },
387
        success: function(json) {
388
            switch(json.status) {
389
                case 'UNAUTHORIZED':
390
                    alert(_("Error : You do not have the permissions necessary to use this functionality."));
391
                    break;
392
                case 'OK':
393
                    updateHeadingLinks(json.links);
394
                    break;
395
            }
396
        },
397
        complete: function() {
398
            $("#loading").hide();
399
        }
400
    });
401
}
402
403
404
function PopupMARCFieldDoc(field) {
405
    [% IF Koha.Preference('marcfielddocurl') %]
406
        var docurl = "[% Koha.Preference('marcfielddocurl').replace('"','&quot;') | html %]";
407
        docurl = docurl.replace("{MARC}", "[% marcflavour | html %]");
408
        docurl = docurl.replace("{FIELD}", ""+field);
409
        docurl = docurl.replace("{LANG}", "[% lang | html %]");
410
        window.open(docurl);
411
    [% ELSIF ( marcflavour == 'MARC21' ) %]
412
        _MARC21FieldDoc(field);
413
    [% ELSIF ( marcflavour == 'UNIMARC' ) %]
414
        _UNIMARCFieldDoc(field);
415
    [% END %]
416
}
181
    function confirmnotdup(redirect){
417
    function confirmnotdup(redirect){
182
        $("#confirm_not_duplicate").attr("value","1");
418
        $("#confirm_not_duplicate").attr("value","1");
183
        $("#redirect").attr("value",redirect);
419
        $("#redirect").attr("value",redirect);
Lines 587-592 Link Here
587
                        [% ELSE %]
823
                        [% ELSE %]
588
                            <div class="btn-group"><a class="btn btn-default" href="#" id="z3950search"><i class="fa fa-search"></i> Z39.50/SRU search</a></div>
824
                            <div class="btn-group"><a class="btn btn-default" href="#" id="z3950search"><i class="fa fa-search"></i> Z39.50/SRU search</a></div>
589
                        [% END %]
825
                        [% END %]
826
                        [% IF ( CAN_user_editauthorities ) %]
827
                            <div class="btn-group"><a class="btn btn-default" href="#" id="linkerbutton"><i class="fa fa-refresh"></i> Link authorities automatically</a></div>
828
                        [% END %]
590
                    [% END %]
829
                    [% END %]
591
830
592
                    <div class="btn-group">
831
                    <div class="btn-group">
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/z3950_auth_search.tt (-1 / +2 lines)
Lines 20-25 Link Here
20
        <form method="post" action="z3950_auth_search.pl" name="f" class="checkboxed">
20
        <form method="post" action="z3950_auth_search.pl" name="f" class="checkboxed">
21
        <input type="hidden" name="op" id="op" value="do_search" />
21
        <input type="hidden" name="op" id="op" value="do_search" />
22
        <input type="hidden" name="authid" value="[% authid | html %]" />
22
        <input type="hidden" name="authid" value="[% authid | html %]" />
23
        <input type="hidden" name="index" value="[% index | html %]" />
23
            <div class="row">
24
            <div class="row">
24
            <div class="col-xs-6">
25
            <div class="col-xs-6">
25
                <fieldset class="rows">
26
                <fieldset class="rows">
Lines 94-100 Link Here
94
                    </a>
95
                    </a>
95
                    <ul class="dropdown-menu pull-right" role="menu" aria-labelledby="cataloguesearchactions[% breeding_loo.breedingid | html %]">
96
                    <ul class="dropdown-menu pull-right" role="menu" aria-labelledby="cataloguesearchactions[% breeding_loo.breedingid | html %]">
96
                        <li><a href="/cgi-bin/koha/catalogue/showmarc.pl?importid=[% breeding_loo.breedingid | uri %]" class="previewMARC"><i class="fa fa-eye"></i> MARC preview</a></li>
97
                        <li><a href="/cgi-bin/koha/catalogue/showmarc.pl?importid=[% breeding_loo.breedingid | uri %]" class="previewMARC"><i class="fa fa-eye"></i> MARC preview</a></li>
97
                        <li><a href="#" class="import_record" data-breedingid="[% breeding_loo.breedingid | html %]" data-heading_code="[% breeding_loo.heading_code | html %]" data-authid="[% breeding_loo.authid | html %]"><i class="fa fa-download"></i> Import</a></li>
98
                        <li><a href="#" class="import_record" data-breedingid="[% breeding_loo.breedingid | html %]" data-heading_code="[% breeding_loo.heading_code | html %]" data-authid="[% breeding_loo.authid | html %]" data-index="[% index | html %]" ><i class="fa fa-download"></i> Import</a></li>
98
                    </ul>
99
                    </ul>
99
                </div>
100
                </div>
100
            </td>
101
            </td>
(-)a/koha-tmpl/intranet-tmpl/prog/js/cataloging.js (+6 lines)
Lines 187-192 function CloneField(index, hideMarc, advancedMARCEditor) { Link Here
187
            for( j = 0 ; j < inputs.length ; j++ ) {
187
            for( j = 0 ; j < inputs.length ; j++ ) {
188
                if(inputs[j].getAttribute("id") && inputs[j].getAttribute("id").match(/^tag_/) ){
188
                if(inputs[j].getAttribute("id") && inputs[j].getAttribute("id").match(/^tag_/) ){
189
                    inputs[j].value = "";
189
                    inputs[j].value = "";
190
191
                    //Remove the color added by the automatic linker
192
                    $(inputs[j]).css({backgroundColor:""});
190
                }
193
                }
191
            }
194
            }
192
            var textareas = divs[i].getElementsByTagName('textarea');
195
            var textareas = divs[i].getElementsByTagName('textarea');
Lines 196-201 function CloneField(index, hideMarc, advancedMARCEditor) { Link Here
196
                }
199
                }
197
            }
200
            }
198
201
202
            // Remove the status icons added by the automatic linker
203
            $(divs[i]).find('.subfield_status').remove();
204
199
            inputs[0].setAttribute('id',inputs[0].getAttribute('id')+new_key);
205
            inputs[0].setAttribute('id',inputs[0].getAttribute('id')+new_key);
200
            inputs[0].setAttribute('name',inputs[0].getAttribute('name')+new_key);
206
            inputs[0].setAttribute('name',inputs[0].getAttribute('name')+new_key);
201
207
(-)a/koha-tmpl/intranet-tmpl/prog/js/z3950_search.js (-3 / +4 lines)
Lines 1-11 Link Here
1
/* global __ total_pages */
1
/* global __ total_pages */
2
//z3950_search.js for Authorities, Bib records and Acquisitions module
2
//z3950_search.js for Authorities, Bib records and Acquisitions module
3
function Import(Breeding, recordid, AuthType, FrameworkCode) {
3
function Import(Breeding, recordid, AuthType, FrameworkCode, index) {
4
4
5
    if ( AuthType == false ) {
5
    if ( AuthType == false ) {
6
        opener.document.location="../cataloguing/addbiblio.pl?biblionumber="+recordid+"&z3950=1&frameworkcode="+FrameworkCode+"&breedingid="+Breeding;
6
        opener.document.location="../cataloguing/addbiblio.pl?biblionumber="+recordid+"&z3950=1&frameworkcode="+FrameworkCode+"&breedingid="+Breeding;
7
    } else {
7
    } else {
8
        opener.document.location="../authorities/authorities.pl?breedingid="+Breeding+"&authtypecode="+AuthType+"&authid="+recordid;
8
        opener.document.location="../authorities/authorities.pl?breedingid="+Breeding+"&authtypecode="+AuthType+"&authid="+recordid+"&index="+index;
9
    }
9
    }
10
    window.close();
10
    window.close();
11
    return false;
11
    return false;
Lines 141-150 $( document ).ready( function() { Link Here
141
        var data_authid = $( this ).data( "authid" );
141
        var data_authid = $( this ).data( "authid" );
142
        var data_biblionumber = $( this ).data( "biblionumber" );
142
        var data_biblionumber = $( this ).data( "biblionumber" );
143
        var data_frameworkcode = $( this ).data( "frameworkcode" );
143
        var data_frameworkcode = $( this ).data( "frameworkcode" );
144
        var data_index = $( this ).data( "index" );
144
        if ( data_headingcode == undefined ) {
145
        if ( data_headingcode == undefined ) {
145
            Import( data_breedingid, data_biblionumber, false , data_frameworkcode );
146
            Import( data_breedingid, data_biblionumber, false , data_frameworkcode );
146
        } else {
147
        } else {
147
            Import( data_breedingid, data_authid, data_headingcode );
148
            Import( data_breedingid, data_authid, data_headingcode, "", data_index );
148
        }
149
        }
149
        return false;
150
        return false;
150
    });
151
    });
(-)a/svc/cataloguing/automatic_linker.pl (+61 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Bouzid Fergani, 2020   - inLibro
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 3 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
use CGI;
22
use CGI::Cookie;
23
use JSON;
24
use C4::Auth;
25
use C4::Biblio;
26
use C4::Context;
27
28
my $input = new CGI;
29
print $input->header('application/json');
30
31
# Check the user's permissions
32
my %cookies = CGI::Cookie->fetch;
33
my $sessid = $cookies{'CGISESSID'}->value || $input->param('CGISESSID');
34
my ( $auth_status, $auth_sessid ) =
35
  C4::Auth::check_cookie_auth( $sessid, { editauthorities => 1, editcatalogue => 1 } );
36
if ( $auth_status ne "ok" ) {
37
    print to_json( { status => 'UNAUTHORIZED' } );
38
    exit 0;
39
}
40
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"}]}
43
#
44
# tag = the tag number of the field
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)
47
48
my $json;
49
50
my $record = TransformHtmlToMarc($input,1);
51
52
my ( $headings_changed, $results ) = BiblioAutoLink (
53
    $record,
54
    $input->param('frameworkcode'),
55
    1
56
);
57
58
$json->{status} = 'OK';
59
$json->{links} = $results->{details} || '';
60
61
print to_json($json);
(-)a/t/Biblio.t (-1 / +1 lines)
Lines 157-160 warnings_like { $ret = UpdateTotalIssues() } Link Here
157
    "UpdateTotalIssues returns carped warnings if biblio record does not exist";
157
    "UpdateTotalIssues returns carped warnings if biblio record does not exist";
158
158
159
ok( !defined $ret, 'UpdateTotalIssues returns carped warning if biblio record does not exist');
159
ok( !defined $ret, 'UpdateTotalIssues returns carped warning if biblio record does not exist');
160
160
1;
(-)a/t/db_dependent/Biblio.t (-3 / +25 lines)
Lines 705-711 subtest 'ModBiblio called from linker test' => sub { Link Here
705
};
705
};
706
706
707
subtest "LinkBibHeadingsToAuthorities record generation tests" => sub {
707
subtest "LinkBibHeadingsToAuthorities record generation tests" => sub {
708
    plan tests => 6;
708
    plan tests => 12;
709
709
710
    # Set up mocks to ensure authorities are generated
710
    # Set up mocks to ensure authorities are generated
711
    my $biblio_mod = Test::MockModule->new( 'C4::Linker::Default' );
711
    my $biblio_mod = Test::MockModule->new( 'C4::Linker::Default' );
Lines 739-744 subtest "LinkBibHeadingsToAuthorities record generation tests" => sub { Link Here
739
        "The generated record contains the correct subfields"
739
        "The generated record contains the correct subfields"
740
    );
740
    );
741
741
742
    #Add test for this case using verbose
743
    my ( $num_headings_changed, $results ) = LinkBibHeadingsToAuthorities($linker, $record, "",undef, 1);
744
    my $details = $results->{details};
745
    is( $num_headings_changed, 1, 'We changed the one we passed' );
746
    is( $results->{details}->[0]->{status}, 'CREATED', "We added an authority record for the heading using verbose");
747
748
    # Now we check the authority record itself
749
    my $authority = GetAuthority($results->{details}->[0]->{authid});
750
751
    is( $authority->field('150')->as_string(),
752
         "Beach city Weirdness Fiction Books 21st Century Fish Stew Pizza",
753
         "The generated record contains the correct subfields when using verbose"
754
    );
755
742
    # Example series link with volume and punctuation
756
    # Example series link with volume and punctuation
743
    $record = MARC::Record->new();
757
    $record = MARC::Record->new();
744
    $field = MARC::Field->new('800','','','a' => 'Tolkien, J. R. R.', 'q' => '(John Ronald Reuel),', 'd' => '1892-1973.', 't' => 'Lord of the rings ;', 'v' => '1');
758
    $field = MARC::Field->new('800','','','a' => 'Tolkien, J. R. R.', 'q' => '(John Ronald Reuel),', 'd' => '1892-1973.', 't' => 'Lord of the rings ;', 'v' => '1');
Lines 759-766 subtest "LinkBibHeadingsToAuthorities record generation tests" => sub { Link Here
759
        "The generated record contains the correct subfields"
773
        "The generated record contains the correct subfields"
760
    );
774
    );
761
775
776
    # The same exemple With verbose
777
    ( $num_headings_changed, $results ) = LinkBibHeadingsToAuthorities($linker, $record, "",undef, 1);
778
    is( $num_headings_changed, 1, 'We changed the one we passed' );
779
    is( $results->{details}->[0]->{status}, 'CREATED', "We added an authority record for the heading using verbose");
762
780
763
781
    # Now we check the authority record itself
782
    my $authority = GetAuthority($results->{details}->[0]->{authid});
783
    is( $authority->field('100')->as_string(),
784
         "Tolkien, J. R. R. (John Ronald Reuel), 1892-1973. Lord of the rings",
785
         "The generated record contains the correct subfields"
786
    );
764
};
787
};
765
788
766
# Cleanup
789
# Cleanup
767
- 

Return to bug 11299