From c307a2cf9bbe171138946ab1b1a82c4acaa49525 Mon Sep 17 00:00:00 2001
From: Bouzid Fergani <bouzid.fergani@inlibro.com>
Date: Wed, 6 Nov 2013 10:49:09 -0500
Subject: [PATCH] Bug 11299 - Add a button to the biblio edition page to
automatically add authority links in the current biblio record via AJAX. Also
adds a button to easily create missing authority records.
add authority type in the form to create the missing authority.
when authority was found, the 600$9 field have the authid.
Testing scenario (Creating an authority record for a failed automatic link) :
* In you system preferences, deactivate the "AutoCreateAuthorities" preference.
* Go to the biblio record creation form to create a new biblio record. (koha/cataloguing/addbiblio.pl)
* Click the "Link authorities automatically" button. A message should appear, telling the user "No authority link was changed."
* Add random informations in field 600$a of the biblio record.
* Click the "Link authorities automatically" button.
* if matching authority was found, The message box should now show "600 - A matching authority was found in the local database".
* if no matching authority was found, the message box should now show "600 - No matching authority found.". For this scenario, we want the authority match to have failed.
* The 600$9 field should now be red and icons should have appeared next to it. Click on the "create authority" icon.
* A popup will appear, containing a form to create the missing authority. The form should be pre-filled, a the informations in the 600$a field of the biblio should be in the 100$a field of this new authority record.
* Fill in the form and click the "Save" button
* The 600$9 field in the biblio record should now be back to normal and have the authid of the authority record that was just created.
* Click the "Link authorities automatically" button again. The message box should now show "No authority link was changed.".
---
C4/Biblio.pm | 138 +++++++++++++-
C4/Linker.pm | 5 +-
C4/Linker/Default.pm | 2 +-
authorities/authorities.pl | 22 ++-
cataloguing/automatic_linker.pl | 74 ++++++++
.../prog/en/modules/authorities/authorities.tt | 3 +
.../authorities/blinddetail-biblio-search.tt | 24 ++-
.../prog/en/modules/cataloguing/addbiblio.tt | 202 ++++++++++++++++++++-
koha-tmpl/intranet-tmpl/prog/img/approve.gif | Bin 0 -> 204 bytes
koha-tmpl/intranet-tmpl/prog/img/deny.gif | Bin 0 -> 381 bytes
koha-tmpl/intranet-tmpl/prog/js/cataloging.js | 6 +
t/Biblio.t | 1 +
12 files changed, 457 insertions(+), 20 deletions(-)
create mode 100755 cataloguing/automatic_linker.pl
create mode 100644 koha-tmpl/intranet-tmpl/prog/img/approve.gif
create mode 100644 koha-tmpl/intranet-tmpl/prog/img/deny.gif
diff --git a/C4/Biblio.pm b/C4/Biblio.pm
index ef2e432..75f5c6c 100644
--- a/C4/Biblio.pm
+++ b/C4/Biblio.pm
@@ -481,7 +481,7 @@ sub BiblioAutoLink {
=head2 LinkBibHeadingsToAuthorities
- my $num_headings_changed, %results = LinkBibHeadingsToAuthorities($linker, $marc, $frameworkcode, [$allowrelink]);
+ my $num_headings_changed, %results = LinkBibHeadingsToAuthorities($linker, $marc, $frameworkcode, [$allowrelink, $verbose]);
Links bib headings to authority records by checking
each authority-controlled field in the C<MARC::Record>
@@ -503,6 +503,7 @@ sub LinkBibHeadingsToAuthorities {
my $bib = shift;
my $frameworkcode = shift;
my $allowrelink = shift;
+ my $verbose = shift;
my %results;
if (!$bib) {
carp 'LinkBibHeadingsToAuthorities called on undefined bib record';
@@ -510,7 +511,6 @@ sub LinkBibHeadingsToAuthorities {
}
require C4::Heading;
require C4::AuthoritiesMarc;
-
$allowrelink = 1 unless defined $allowrelink;
my $num_headings_changed = 0;
foreach my $field ( $bib->fields() ) {
@@ -523,24 +523,30 @@ sub LinkBibHeadingsToAuthorities {
if ( defined $current_link && (!$allowrelink || !C4::Context->preference('LinkerRelink')) )
{
$results{'linked'}->{ $heading->display_form() }++;
+ push(@{$results{'details'}}, { tag => $field->tag(), authid => $current_link, status => 'UNCHANGED'}) if $verbose;
next;
}
- my ( $authid, $fuzzy ) = $linker->get_link($heading);
+ my ( $authid, $fuzzy, $status ) = $linker->get_link($heading);
if ($authid) {
$results{ $fuzzy ? 'fuzzy' : 'linked' }
->{ $heading->display_form() }++;
- next if defined $current_link and $current_link == $authid;
+ if(defined $current_link and $current_link == $authid) {
+ push(@{$results{'details'}}, { tag => $field->tag(), authid => $current_link, status => 'UNCHANGED'}) if $verbose;
+ next;
+ }
$field->delete_subfield( code => '9' ) if defined $current_link;
$field->add_subfields( '9', $authid );
$num_headings_changed++;
+ push(@{$results{'details'}}, { tag => $field->tag(), authid => $authid, status => $status || 'LOCAL_FOUND'}) if $verbose;
}
else {
if ( defined $current_link
&& (!$allowrelink || C4::Context->preference('LinkerKeepStale')) )
{
$results{'fuzzy'}->{ $heading->display_form() }++;
+ push(@{$results{'details'}}, { tag => $field->tag(), authid => $current_link, status => 'UNCHANGED'}) if $verbose;
}
elsif ( C4::Context->preference('AutoCreateAuthorities') ) {
if ( _check_valid_auth_link( $current_link, $field ) ) {
@@ -594,32 +600,35 @@ sub LinkBibHeadingsToAuthorities {
}
# warn "AUTH RECORD ADDED : ".$marcrecordauth->as_formatted;
+ $authid = AddAuthorityFromHeading($heading, $field, $bib);
- $authid =
- C4::AuthoritiesMarc::AddAuthority( $marcrecordauth, '',
- $heading->auth_type() );
$field->add_subfields( '9', $authid );
$num_headings_changed++;
$linker->update_cache($heading, $authid);
$results{'added'}->{ $heading->display_form() }++;
+ push(@{$results{'details'}}, { tag => $field->tag(), authid => $authid, status => 'CREATED'}) if $verbose;
}
}
elsif ( defined $current_link ) {
if ( _check_valid_auth_link( $current_link, $field ) ) {
$results{'linked'}->{ $heading->display_form() }++;
+ push(@{$results{'details'}}, { tag => $field->tag(), authid => $authid, status => 'UNCHANGED'}) if $verbose;
}
else {
$field->delete_subfield( code => '9' );
$num_headings_changed++;
$results{'unlinked'}->{ $heading->display_form() }++;
+ push(@{$results{'details'}}, { tag => $field->tag(), authid => undef, status => 'NONE_FOUND'}) if $verbose;
}
}
else {
$results{'unlinked'}->{ $heading->display_form() }++;
+ push(@{$results{'details'}}, { tag => $field->tag(), authid => undef, status => 'NONE_FOUND'}) if $verbose;
}
}
}
+ push(@{$results{'details'}}, { tag => '', authid => undef, status => 'UNCHANGED'}) unless %results;
return $num_headings_changed, \%results;
}
@@ -647,6 +656,121 @@ sub _check_valid_auth_link {
return ($field->as_string('abcdefghijklmnopqrstuvwxyz') eq $authorized_heading);
}
+=head2 AddAuthorityFromHeading
+
+ my $authid = AddAuthorityFromHeading($heading, $field, [$bib]);
+
+Creates a new authority from an heading and its associated field.
+
+Returns the id of the newly created authority.
+
+=cut
+
+sub AddAuthorityFromHeading {
+ my $heading = shift;
+ my $field = shift;
+ my $bib = shift;
+
+ if(!defined $heading || !defined $field || !defined $bib){
+ return 0;
+ }
+ my $authtypedata =
+ Koha::Authority::Types->find( $heading->auth_type() );
+ my $marcrecordauth = MARC::Record->new();
+ if ( C4::Context->preference('marcflavour') eq 'MARC21' ) {
+ $marcrecordauth->leader(' nz a22 o 4500');
+ SetMarcUnicodeFlag( $marcrecordauth, 'MARC21' );
+ }
+ my $authfield =
+ MARC::Field->new( $authtypedata->auth_tag_to_report,
+ '', '', "a" => "" . $field->subfield('a') );
+ map {
+ $authfield->add_subfields( $_->[0] => $_->[1] )
+ if ( $_->[0] =~ /[A-z]/ && $_->[0] ne "a" )
+ } $field->subfields();
+ $marcrecordauth->insert_fields_ordered($authfield);
+
+# bug 2317: ensure new authority knows it's using UTF-8; currently
+# only need to do this for MARC21, as MARC::Record->as_xml_record() handles
+# automatically for UNIMARC (by not transcoding)
+# FIXME: AddAuthority() instead should simply explicitly require that the MARC::Record
+# use UTF-8, but as of 2008-08-05, did not want to introduce that kind
+# of change to a core API just before the 3.0 release.
+
+ if ( C4::Context->preference('marcflavour') eq 'MARC21' ) {
+ $marcrecordauth->insert_fields_ordered(
+ MARC::Field->new(
+ '667', '', '',
+ 'a' => "Machine generated authority record."
+ )
+ );
+ if(defined $bib) {
+ my $cite =
+ $bib->author() . ", "
+ . $bib->title_proper() . ", "
+ . $bib->publication_date() . " ";
+ $cite =~ s/^[\s\,]*//;
+ $cite =~ s/[\s\,]*$//;
+ $cite =
+ "Work cat.: ("
+ . C4::Context->preference('MARCOrgCode') . ")"
+ . $bib->subfield( '999', 'c' ) . ": "
+ . $cite;
+ $marcrecordauth->insert_fields_ordered(
+ MARC::Field->new( '670', '', '', 'a' => $cite ) );
+ }
+
+ # Add correct informations in field 008 and 040 so the authority can be linked correctly in future linkings
+ my $date=POSIX::strftime("%y%m%d",localtime);
+ my @heading_use = qw(b b b);
+ my $thesaurus = '|';
+
+ if ($heading->{'subject_added_entry'}) {
+ $heading_use[1] = 'a';
+ # Thesaurus treatment
+ my %thesaurus_conv = ('lcsh'=>'a','lcac'=>'b','mesh'=>'c','nal'=>'d','notspecified'=>'n','cash'=>'k','rvm'=>'v');
+ $thesaurus = 'z';
+ $thesaurus = $thesaurus_conv{$heading->{'thesaurus'}} if exists $thesaurus_conv{$heading->{'thesaurus'}};
+ if($thesaurus eq 'z')
+ {
+ $marcrecordauth->insert_fields_ordered(
+ MARC::Field->new('040','','','f'=>$heading->{'thesaurus'})
+ );
+ }
+ }
+ if ($heading->{'series_added_entry'}) {
+ $heading_use[2] = 'a';
+ }
+ if (not $heading->{'subject_added_entry'} and not $heading->{'series_added_entry'}) {
+ $heading_use[0] = 'a';
+ }
+
+ # Get a valid default value for field 008
+ my $default_008 = C4::Context->preference('MARCAuthorityControlField008');
+ if(!$default_008 or length($default_008)<34) {
+ $default_008 = '|| aca||aabn | a|a d';
+ }
+ else {
+ $default_008 = substr($default_008,0,34)
+ }
+
+ # Insert the date, thesaurus and heading_use into field 008
+ my $f008 = $date . $default_008;
+ substr($f008, 11, 1) = $thesaurus;
+ substr($f008, 14, 3) = join('', @heading_use);
+
+ $marcrecordauth->insert_fields_ordered(
+ MARC::Field->new('008',$f008)
+ );
+ }
+
+# warn "AUTH RECORD ADDED : ".$marcrecordauth->as_formatted;
+
+ my $authid = C4::AuthoritiesMarc::AddAuthority( $marcrecordauth, '', $heading->auth_type() );
+ return $authid;
+}
+
+
=head2 GetRecordValue
my $values = GetRecordValue($field, $record, $frameworkcode);
diff --git a/C4/Linker.pm b/C4/Linker.pm
index 969d2ea..ec7b035 100644
--- a/C4/Linker.pm
+++ b/C4/Linker.pm
@@ -30,8 +30,9 @@ C4::Linker - Base class for linking authorities to bibliographic records
Base class for C4::Linker::X. Subclasses need to provide the following methods
B<get_link ($field)> - return the authid for the authority that should be
-linked to the provided MARC::Field object, and a boolean to indicate whether
-the match is "fuzzy" (the semantics of "fuzzy" are up to the individual plugin).
+linked to the provided MARC::Field object, a boolean to indicate whether
+the match is "fuzzy" (the semantics of "fuzzy" are up to the individual plugin),
+and an optional 'status' string giving more informations on the link status.
In order to handle authority limits, get_link should always end with:
return $self->SUPER::_handle_auth_limit($authid), $fuzzy;
diff --git a/C4/Linker/Default.pm b/C4/Linker/Default.pm
index b39557c..0ea7fe2 100644
--- a/C4/Linker/Default.pm
+++ b/C4/Linker/Default.pm
@@ -42,7 +42,7 @@ sub get_link {
# look for matching authorities
my $authorities = $heading->authorities(1); # $skipmetadata = true
- if ( $behavior eq 'default' && $#{$authorities} == 0 ) {
+ if ( $behavior eq 'default' && $#{$authorities} >= 0 ) {
$authid = $authorities->[0]->{'authid'};
}
elsif ( $behavior eq 'first' && $#{$authorities} >= 0 ) {
diff --git a/authorities/authorities.pl b/authorities/authorities.pl
index 1e49d96..1e04cde 100755
--- a/authorities/authorities.pl
+++ b/authorities/authorities.pl
@@ -565,6 +565,22 @@ my $myindex = $input->param('index');
my $linkid=$input->param('linkid');
my $authtypecode = $input->param('authtypecode');
my $breedingid = $input->param('breedingid');
+my $biblioindex = $input->param('biblioindex'); # Used when in popup mode to send the new autority infos to the parent biblio
+
+if($biblioindex and !$authid){
+ require C4::Heading;
+
+ my $record = TransformHtmlToMarc( $input );
+
+ # Get the first heading found in the biblio informations
+ foreach my $field ( $record->fields() ) {
+ my $heading = C4::Heading->new_from_bib_field($field);
+ next unless defined $heading;
+
+ # Create a new authority using the heading informations
+ $authid = C4::Biblio::AddAuthorityFromHeading($heading, $field);
+ }
+}
my $dbh = C4::Context->dbh;
if(!$authtypecode) {
@@ -579,7 +595,7 @@ my ($template, $loggedinuser, $cookie)
flagsrequired => {editauthorities => 1},
debug => 1,
});
-$template->param(nonav => $nonav,index=>$myindex,authtypecode=>$authtypecode,breedingid=>$breedingid,);
+$template->param(nonav => $nonav,index=>$myindex,authtypecode=>$authtypecode,breedingid=>$breedingid,biblioindex=>$biblioindex);
$tagslib = GetTagsLabels(1,$authtypecode);
$mandatory_z3950 = GetMandatoryFieldZ3950($authtypecode);
@@ -624,7 +640,9 @@ if ($op eq "add") {
} else {
($authid) = AddAuthority($record,$authid,$authtypecode);
}
- if ($myindex) {
+ if ($biblioindex) {
+ print $input->redirect("blinddetail-biblio-search.pl?authid=$authid&index=$biblioindex");
+ } elsif ($myindex) {
print $input->redirect("blinddetail-biblio-search.pl?authid=$authid&index=$myindex");
} else {
print $input->redirect("detail.pl?authid=$authid");
diff --git a/cataloguing/automatic_linker.pl b/cataloguing/automatic_linker.pl
new file mode 100755
index 0000000..8d4958a
--- /dev/null
+++ b/cataloguing/automatic_linker.pl
@@ -0,0 +1,74 @@
+#!/usr/bin/perl
+
+# Frédérick Capovilla, 2011 - Libéo
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+use CGI;
+use CGI::Cookie;
+use JSON;
+use C4::Auth;
+use C4::Biblio;
+use C4::Context;
+
+my $input = new CGI;
+print $input->header('application/json');
+
+# Check the user's permissions
+my %cookies = CGI::Cookie->fetch;
+my $sessid = $cookies{'CGISESSID'}->value || $input->param('CGISESSID');
+my ( $auth_status, $auth_sessid ) =
+ C4::Auth::check_cookie_auth( $sessid, { editauthorities => 1 } );
+if ( $auth_status ne "ok" ) {
+ print to_json( { status => 'UNAUTHORIZED' } );
+ exit 0;
+}
+
+# Link the biblio headings to authorities and return a json containing the status of all the links.
+# Example : {"status":"OK","links":[{"authid":"123","status":"LINK_CHANGED","tag":"650"}]}
+#
+# tag = the tag number of the field
+# authid = the value of the $9 subfield for this tag
+# status = The status of the link (LOCAL_FOUND, NONE_FOUND, MULTIPLE_MATCH, UNCHANGED, CREATED)
+
+my $json;
+
+my $record = TransformHtmlToMarc($input,1);
+
+my $linker_module =
+ "C4::Linker::" . ( C4::Context->preference("LinkerModule") || 'Default' );
+eval { eval "require $linker_module"; };
+if ($@) {
+ $linker_module = 'C4::Linker::Default';
+ eval "require $linker_module";
+}
+if ($@) {
+ return 0, 0;
+}
+my $linker = $linker_module->new(
+ { 'options' => C4::Context->preference("LinkerOptions") } );
+
+my ( $headings_changed, $results ) = LinkBibHeadingsToAuthorities(
+ $linker, $record,
+ $input->param('frameworkcode'),
+ C4::Context->preference("CatalogModuleRelink") || '', 1
+);
+
+$json->{status} = 'OK';
+$json->{links} = $results->{details} || '';
+
+print to_json($json);
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/authorities.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/authorities.tt
index ceb6e60..779e225 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/authorities.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/authorities.tt
@@ -201,6 +201,9 @@ function confirmnotdup(redirect){
<input type="hidden" name="authtypecode" value="[% authtypecode %]" />
<input type="hidden" name="authid" value="[% authid %]" />
<input type="hidden" name="index" value="[% index %]" />
+ [% IF ( biblioindex ) %]
+ <input type="hidden" name="biblioindex" value="[% biblioindex %]" />
+ [% END %]
<input type="hidden" value="0" id="confirm_not_duplicate" name="confirm_not_duplicate" />
<div id="toolbar" class="btn-toolbar">
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/blinddetail-biblio-search.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/blinddetail-biblio-search.tt
index f6ab158..dec21ef 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/blinddetail-biblio-search.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/blinddetail-biblio-search.tt
@@ -5,9 +5,19 @@
//<![CDATA[
$(document).ready(function(){
var index_start = "[% index %]";
- var whichfield;
+ var whichfield = null;
+
+ // Loop through opener windows and try to find the basewindow and the form field we need to fill
+ var basewindow = window;
+ var parents_to_close = [];
try {
- whichfield = opener.opener.document.getElementById(index_start);
+ while(whichfield === null) {
+ basewindow = basewindow.opener;
+ whichfield = basewindow.document.getElementById(index_start);
+ if(whichfield === null) {
+ parents_to_close.unshift(basewindow);
+ }
+ }
} catch(e) {
return;
}
@@ -100,13 +110,19 @@
[% ELSE %]
if(code.value=='9'){
subfield.value = "[% authid |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]";
- break;
+ // Clean the field if it was modified by the automatic linker
+ $(subfield).siblings('.subfield_status').remove();
+ $(subfield).css({backgroundColor:''});
}
[% END %]
}
}
- opener.close();
+ // Close all parent windows, but not the basewindow
+ while(parents_to_close.length != 0) {
+ parents_to_close.shift().close();
+ }
+
window.close();
return false;
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt
index 7a50096..e39bcb0 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt
@@ -76,6 +76,10 @@
[% END %]
});
+ $("#linkerbutton").click(function(){
+ AutomaticLinker();
+ });
+
$("#saverecord").click(function(){
$(".btn-group").removeClass("open");
onOption();
@@ -158,6 +162,194 @@ function PopupZ3950() {
}
}
+function addCreateAuthorityButton(tag_subfield_line, tag, index) {
+ var title = _("Create authority");
+ var elem = $('<a class="subfield_status" href="#"><img src="[% interface %]/[% theme %]/img/edit-tag.png" title="' + title + '" /></a>');
+ tag_subfield_line.append(elem);
+
+ elem.click(function() {
+ var biblioindex = $(this).parents('.subfield_line').find('input').eq(1).attr('id');
+ var popup = window.open("", "new_auth_popup",'width=700,height=550,toolbar=false,scrollbars=yes');
+
+ if(popup !== null) {
+ // Create a new form that will be POSTed in the new window
+ var form = $('<form>').attr({
+ method: 'post',
+ action: "../authorities/authorities.pl",
+ target: "new_auth_popup"
+ });
+
+ // Add the biblioindex
+ form.append($('<input>').attr({
+ type: 'hidden',
+ name: 'biblioindex',
+ value: biblioindex
+ }));
+ //add the authtypecode
+ form.append($('<input>').attr({
+ type: 'hidden',
+ name: 'authtypecode',
+ value: $("#authtypecode").val()
+ }));
+
+
+ // Get all form datas for the current heading field
+ $('.tag[id^=tag_' + tag + '_]').eq(index).find(':input').each(function(){
+ form.append($('<input>').attr({
+ type: 'hidden',
+ name: this.name,
+ value: $(this).val()
+ }));
+ });
+
+ // We need to add the temporary form to the body so we can submit it
+ $('body').append(form);
+ form.submit();
+ form.remove();
+ }
+
+ return false;
+ });
+}
+
+/**
+ * Updates the authid for every heading field
+ * Adds visual feedback for the changes made on the form.
+ */
+function updateHeadingLinks(links) {
+ var current_tag = '';
+ var tag_index = 0;
+
+ // Delete the old message dialog and create a new one
+ $('#autolinker_dialog').remove();
+ var message_dialog = $('<div id="autolinker_dialog" class="dialog"><strong>' + _("Automatic authority link results:") + '</strong><ul></ul></div>');
+ var message_dialog_ul = message_dialog.find('ul');
+
+ $.each(links, function(index, heading) {
+ if(current_tag == heading.tag) {
+ tag_index++;
+ }
+ else {
+ current_tag = heading.tag;
+ tag_index = 0;
+ }
+
+ // Find the $9 field to update
+ var tag_subfield_line = $('.subfield_line[id^=subfield' + heading.tag + '9]').eq(tag_index);
+ var subfield = tag_subfield_line.children('.input_marceditor').eq(0);
+
+ // Delete the old status if one exists
+ tag_subfield_line.children('.subfield_status').remove();
+ subfield.css({backgroundColor:''});
+
+ // If the field wasn't modified. Skip it.
+ if(heading.status == 'UNCHANGED') {
+ return;
+ }
+
+
+ // Make the subfield line visible and update its value
+ tag_subfield_line.show();
+ subfield.val(heading.authid);
+
+ // Add the new status
+ var image = 'deny.gif';
+ var message = '';
+ var field_color = '#FFAAAA';
+ switch(heading.status) {
+ case 'LOCAL_FOUND':
+ image = 'approve.gif';
+ message = _("A matching authority was found in the local database.");
+ field_color = '#99FF99';
+ break;
+ case 'CREATED':
+ image = 'approve.gif';
+ message = _("No matching authority found. A new authority was created automatically.");
+ field_color = '#99FF99';
+ break;
+ case 'MULTIPLE_MATCH':
+ message = _("More than one local match found. Possibly a duplicate authority!");
+ break;
+ case 'NONE_FOUND':
+ message = _("No matching authority found.");
+ break;
+ default:
+ message = heading.status;
+ break;
+ }
+
+ subfield.css({backgroundColor:field_color});
+ tag_subfield_line.append('<img class="subfield_status" src="[% interface %]/[% theme %]/img/' + image + '" title="' + message + '" />');
+
+ // Add the message to the dialog
+ message_dialog_ul.append('<li><strong>' + heading.tag + '</strong> - ' + message + '</li>');
+
+ // Add a link to create a new authority if none was found
+ if(heading.status == 'NONE_FOUND') {
+ addCreateAuthorityButton(tag_subfield_line, heading.tag, tag_index);
+ }
+ });
+
+ if(message_dialog.find('li').length == 0) {
+ message_dialog_ul.append("<li>" + _("No authority link was changed.") + "</li>");
+ }
+ $('#addbibliotabs').before(message_dialog);
+}
+
+/**
+ * Use an ajax request to automatically find authority links for the current record
+ */
+function AutomaticLinker() {
+ // Show the Loading overlay
+ $("#loading").show();
+
+ // Remove fields that are completely empty
+ $('#f').find('.tag').each(function() {
+ var empty = true;
+ $(this).find('.input_marceditor').each(function() {
+ if($(this).val() != '') {
+ empty = false;
+ return false;
+ }
+ });
+ if(empty) {
+ UnCloneField($(this).attr('id'));
+ }
+ });
+
+ // Get all the form values to post via AJAX
+ var form_data = {};
+ $('#f').find(':input').each(function(){
+ form_data[this.name] = $(this).val();
+ });
+ delete form_data[''];
+
+ // Send the data to automatic_linker.pl
+ $.ajax({
+ url:'/cgi-bin/koha/cataloguing/automatic_linker.pl',
+ type:'post',
+ data: form_data,
+ dataType: 'json',
+ error: function(xhr) {
+ alert("Error : \n" + xhr.responseText);
+ },
+ success: function(json) {
+ switch(json.status) {
+ case 'UNAUTHORIZED':
+ alert(_("Error : You do not have the permissions necessary to use this functionality."));
+ break;
+ case 'OK':
+ updateHeadingLinks(json.links);
+ break;
+ }
+ },
+ complete: function() {
+ $("#loading").hide();
+ }
+ });
+}
+
+
function PopupMARCFieldDoc(field) {
[% IF ( marcflavour == 'MARC21' ) %]
_MARC21FieldDoc(field);
@@ -472,10 +664,6 @@ function Changefwk() {
<div class="btn-group"><a href="#" id="saveandview" class="btn btn-default btn-sm"><i class="fa fa-save"></i> Save</a></div>
[% END %]
- [% UNLESS (circborrowernumber) %][%# Hide in fast cataloging %]
- <div class="btn-group"><a class="btn btn-default btn-sm" href="#" id="z3950search"><i class="fa fa-search"></i> Z39.50/SRU search</a></div>
- [% END %]
-
<div class="btn-group">
<button class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown"><i class="fa fa-cog"></i> Settings <span class="caret"></span></button>
<ul id="settings-menu" class="dropdown-menu">
@@ -516,6 +704,11 @@ function Changefwk() {
</ul>
</div>
[% UNLESS (circborrowernumber) %][%# Hide in fast cataloging %]
+ <div class="btn-group"><a class="btn btn-default btn-sm" href="#" id="linkerbutton"><i class="fa fa-refresh"></i> Link authorities automatically</a></div>
+ <div class="btn-group"><a class="btn btn-default btn-sm" href="#" id="z3950search"><i class="fa fa-search"></i> Z39.50/SRU search</a></div>
+ [% IF Koha.Preference( 'EnableAdvancedCatalogingEditor' ) == 1 %]
+ <div class="btn-group"><a href="#" id="switcheditor" class="btn btn-small">Switch to advanced editor</a></div>
+ [% END %]
[% IF (biblionumber) %]
[% IF ( BiblioDefaultViewmarc ) %]
<div class="btn-group">
@@ -662,6 +855,7 @@ function Changefwk() {
<input type="text" id="[%- mv.id -%]" name="[%- mv.name -%]" value="[%- mv.value -%]" class="input_marceditor" tabindex="1" size="[%- mv.size -%]" maxlength="[%- mv.maxlength -%]" />
[% END %]
[% IF ( mv.authtype ) %]
+ <input type="hidden" name="authtypecode" id="authtypecode" value="[% mv.authtype %]" />
<span class="subfield_controls"><a href="#" class="buttonDot tag_editor" onclick="openAuth(this.parentNode.parentNode.getElementsByTagName('input')[1].id,'[%- mv.authtype -%]','biblio'); return false;" tabindex="1" title="Tag editor">Tag editor</a></span>
[% END %]
[% ELSIF ( mv.type == 'text_complex' ) %]
diff --git a/koha-tmpl/intranet-tmpl/prog/img/approve.gif b/koha-tmpl/intranet-tmpl/prog/img/approve.gif
new file mode 100644
index 0000000000000000000000000000000000000000..8064cf21415c77d977ea9e6357f144fe9635dc3b
GIT binary patch
literal 204
zcmZ?wbhEHb6k-r!IKsfdFf;A{|NjkVHXE#IKL6%X!u|#8@1GZ#U-04QH;2tV3vM3E
zKe|$3S>^txH}8LX6R>mIg*T52j;#dhBN8b7WMLIyU}Vq%sR!A~!0MTx(3g@qFC)vW
z(@W`e^A05=ku4rFUUF~t-qCyHEK{)WU_x1z4bNf@hDk;;e0>d!3I&=BtjfyA8EhB=
UZiyRwlVvy<v+(umb_ND(01r_^!2kdN
literal 0
HcmV?d00001
diff --git a/koha-tmpl/intranet-tmpl/prog/img/deny.gif b/koha-tmpl/intranet-tmpl/prog/img/deny.gif
new file mode 100644
index 0000000000000000000000000000000000000000..344839541e45ccb88dd22b52b7828c29902a6936
GIT binary patch
literal 381
zcmZ?wbhEHb6k-r!xXQqAhJoSt%a@Ofi@zK@cFV=(&AfTn3=JP7Ctp@l`f=~x|Ns9#
zY~K8=rRDq8s~06C?gR$D=;^s`Y59KLx_>`@T+z}x&(Hts`SVZv_I<l>;bB(RO(&<@
zUS3bCs@^VH^5@;V`?0YvCr>`d!NEW?p!k!8RfK_yK?h_5$WIJxvm9CrJanY`Pb@JC
ze4wLttnJAoNi~a!?#r!m49s{=Ur?@8P-^Nfn6NNFA?6{AvV#Rj_d!O-M3p{H9;tLe
z5f+6c58+fr20qDpFJ5*&MLt1=LN_rUK{hEi4k=lW@P#rGscqbDj6571^1NKa+|r`b
w;sH)_3VBS-F5H5m>=U_|S^AGVv$8NrIOj-atrchP<YJWI-R*VX-I2i>0NV;}BLDyZ
literal 0
HcmV?d00001
diff --git a/koha-tmpl/intranet-tmpl/prog/js/cataloging.js b/koha-tmpl/intranet-tmpl/prog/js/cataloging.js
index eedac25..497e744 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/cataloging.js
+++ b/koha-tmpl/intranet-tmpl/prog/js/cataloging.js
@@ -128,6 +128,9 @@ function CloneField(index, hideMarc, advancedMARCEditor) {
for( j = 0 ; j < inputs.length ; j++ ) {
if(inputs[j].getAttribute("id") && inputs[j].getAttribute("id").match(/^tag_/) ){
inputs[j].value = "";
+
+ //Remove the color added by the automatic linker
+ $(inputs[j]).css({backgroundColor:""});
}
}
var textareas = divs[i].getElementsByTagName('textarea');
@@ -137,6 +140,9 @@ function CloneField(index, hideMarc, advancedMARCEditor) {
}
}
+ // Remove the status icons added by the automatic linker
+ $(divs[i]).find('.subfield_status').remove();
+
inputs[0].setAttribute('id',inputs[0].getAttribute('id')+new_key);
inputs[0].setAttribute('name',inputs[0].getAttribute('name')+new_key);
var id_input;
diff --git a/t/Biblio.t b/t/Biblio.t
index 1cec33b..d2d2b58 100755
--- a/t/Biblio.t
+++ b/t/Biblio.t
@@ -197,4 +197,5 @@ warnings_like { $ret = UpdateTotalIssues() }
ok( !defined $ret, 'UpdateTotalIssues returns carped warning if biblio record does not exist');
+is(C4::Biblio::AddAuthorityFromHeading(), 0, 'AddAuthorityFromHeading returns zero if not passed heading, field or bib');
1;
--
1.9.1