@@ -, +, @@ --- C4/AuthoritiesMarc.pm | 21 +- C4/Biblio.pm | 28 +- C4/Linker/Default.pm | 6 +- C4/UsageStats.pm | 1 + C4/XSLT.pm | 2 +- Koha/Authorities.pm | 16 + authorities/blinddetail-biblio-search.pl | 4 +- authorities/detail.pl | 3 +- cataloguing/addbiblio.pl | 10 +- .../data/mysql/atomicupdate/bug_17511.perl | 8 + installer/data/mysql/mandatory/sysprefs.sql | 1 + .../admin/preferences/authorities.pref | 5 + .../authorities/blinddetail-biblio-search.tt | 3 +- .../en/xslt/MARC21slim2intranetDetail.xsl | 18 +- .../en/xslt/MARC21slim2intranetResults.xsl | 5 +- .../prog/en/xslt/MARC21slimUtils.xsl | 13 +- .../en/xslt/NORMARCslim2intranetDetail.xsl | 17 +- .../en/xslt/NORMARCslim2intranetResults.xsl | 13 +- .../prog/en/xslt/NORMARCslimUtils.xsl | 4 +- .../en/xslt/UNIMARCslim2intranetDetail.xsl | 1 + .../en/xslt/UNIMARCslim2intranetResults.xsl | 1 + .../prog/en/xslt/UNIMARCslimUtils.xsl | 8 +- .../en/xslt/MARC21slim2OPACDetail.xsl | 24 +- .../bootstrap/en/xslt/MARC21slimUtils.xsl | 12 +- .../en/xslt/NORMARCslim2OPACDetail.xsl | 32 +- .../bootstrap/en/xslt/NORMARCslimUtils.xsl | 4 +- .../bootstrap/en/xslt/UNIMARCslimUtils.xsl | 12 +- misc/maintenance/batchAuthorityLinking.pl | 274 ++++++++++++++++++ t/db_dependent/Koha/Authorities.t | 24 ++ 29 files changed, 464 insertions(+), 106 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug_17511.perl create mode 100755 misc/maintenance/batchAuthorityLinking.pl --- a/C4/AuthoritiesMarc.pm +++ a/C4/AuthoritiesMarc.pm @@ -870,6 +870,7 @@ sub BuildSummary { my @seefrom; my @seealso; my @otherscript; + my $authsubfield = Koha::Authorities->authority_linking_subfield; if (C4::Context->preference('marcflavour') eq 'UNIMARC') { # construct UNIMARC summary, that is quite different from MARC21 one # accepted form @@ -904,7 +905,7 @@ sub BuildSummary { heading => $heading, hemain => ( $_->subfield('a') // undef ), search => $heading, - authid => ( $_->subfield('9') // undef ), + authid => ( $_->subfield($authsubfield) // undef ), } } $record->field('5..'); @@ -1003,7 +1004,7 @@ sub BuildSummary { type => scalar $field->subfield('i'), field => $field->tag(), search => $field->as_string($marc21subfields) || '', - authid => $field->subfield('9') || '' + authid => $field->subfield($authsubfield) || '' }; } else { push @seealso, { @@ -1012,7 +1013,7 @@ sub BuildSummary { type => $type, field => $field->tag(), search => $field->as_string($marc21subfields) || '', - authid => $field->subfield('9') || '' + authid => $field->subfield($authsubfield) || '' }; } } @@ -1287,7 +1288,8 @@ sub GenerateHierarchy { sub _get_authid_subfield{ my ($field)=@_; - return $field->subfield('9')||$field->subfield('3'); + my $authsubfield = Koha::Authorities->authority_linking_subfield; + return $field->subfield($authsubfield)||$field->subfield('3'); } =head2 GetHeaderAuthority @@ -1394,6 +1396,7 @@ sub merge { my $authtypeto = $authto ? Koha::Authority::Types->find($authto->authtypecode) : undef; my $auth_tag_to_report_from = $authtypefrom ? $authtypefrom->auth_tag_to_report : ''; my $auth_tag_to_report_to = $authtypeto ? $authtypeto->auth_tag_to_report : ''; + my $authsubfield = Koha::Authorities->authority_linking_subfield; my @record_to; @record_to = $MARCto->field($auth_tag_to_report_to)->subfields() if $auth_tag_to_report_to && $MARCto && $MARCto->field($auth_tag_to_report_to); @@ -1441,7 +1444,7 @@ sub merge { foreach my $tagfield (@$tags_using_authtype) { my $countfrom = 0; # used in strict mode to remove duplicates foreach my $field ( $marcrecord->field($tagfield) ) { - my $auth_number = $field->subfield("9"); # link to authority + my $auth_number = $field->subfield($authsubfield); # link to authority my $tag = $field->tag(); next if !defined($auth_number) || $auth_number ne $mergefrom; $countfrom++; @@ -1461,7 +1464,7 @@ sub merge { $newtag, $controlled_ind->{ind1} // $field->indicator(1), $controlled_ind->{ind2} // $field->indicator(2), - 9 => $mergeto, # Needed to create field, will be moved + $authsubfield => $mergeto, # Needed to create field, will be moved ); my ( @prefix, @postfix ); if ( !$overwrite ) { @@ -1470,7 +1473,7 @@ sub merge { # controlled block, the rest at the end. my $prefix_flag = 1; foreach my $subfield ( $field->subfields ) { - next if $subfield->[0] eq '9'; # skip but leave flag + next if $subfield->[0] eq $authsubfield; # skip but leave flag if ( $skip_subfields->{ $subfield->[0] } ) { # This marks the beginning of the controlled block $prefix_flag = 0; @@ -1496,8 +1499,8 @@ sub merge { } } # Move $9 to the end - $field_to->delete_subfield( code => '9' ); - $field_to->add_subfields( 9 => $mergeto ); + $field_to->delete_subfield( code => $authsubfield ); + $field_to->add_subfields( $authsubfield => $mergeto ); if ($tags_new && @$tags_new) { $marcrecord->delete_field($field); --- a/C4/Biblio.pm +++ a/C4/Biblio.pm @@ -96,6 +96,7 @@ use C4::OAI::Sets; use C4::Debug; use Koha::Caches; +use Koha::Authorities; use Koha::Authority::Types; use Koha::Acquisition::Currencies; use Koha::Biblio::Metadatas; @@ -347,9 +348,10 @@ sub ModBiblio { # Cleaning up invalid fields must be done early or SetUTF8Flag is liable to # throw an exception which probably won't be handled. + my $authsubfield = Koha::Authorities->authority_linking_subfield; foreach my $field ($record->fields()) { if (! $field->is_control_field()) { - if (scalar($field->subfields()) == 0 || (scalar($field->subfields()) == 1 && $field->subfield('9'))) { + if (scalar($field->subfields()) == 0 || (scalar($field->subfields()) == 1 && $field->subfield($authsubfield))) { $record->delete_field($field); } } @@ -557,6 +559,7 @@ sub LinkBibHeadingsToAuthorities { $allowrelink = 1 unless defined $allowrelink; my $num_headings_changed = 0; + my $authsubfield = Koha::Authorities->authority_linking_subfield; foreach my $field ( $bib->fields() ) { if ( defined $tagtolink ) { next unless $field->tag() == $tagtolink ; @@ -565,7 +568,7 @@ sub LinkBibHeadingsToAuthorities { next unless defined $heading; # check existing $9 - my $current_link = $field->subfield('9'); + my $current_link = $field->subfield($authsubfield); if ( defined $current_link && (!$allowrelink || !C4::Context->preference('LinkerRelink')) ) { @@ -579,8 +582,8 @@ sub LinkBibHeadingsToAuthorities { ->{ $heading->display_form() }++; next if defined $current_link and $current_link == $authid; - $field->delete_subfield( code => '9' ) if defined $current_link; - $field->add_subfields( '9', $authid ); + $field->delete_subfield( code => $authsubfield ) if defined $current_link; + $field->add_subfields( $authsubfield, $authid ); $num_headings_changed++; } else { @@ -600,7 +603,7 @@ sub LinkBibHeadingsToAuthorities { $marcrecordauth->leader(' nz a22 o 4500'); SetMarcUnicodeFlag( $marcrecordauth, 'MARC21' ); } - $field->delete_subfield( code => '9' ) + $field->delete_subfield( code => $authsubfield ) if defined $current_link; my @auth_subfields; foreach my $subfield ( $field->subfields() ){ @@ -659,7 +662,7 @@ sub LinkBibHeadingsToAuthorities { $authid = C4::AuthoritiesMarc::AddAuthority( $marcrecordauth, '', $heading->auth_type() ); - $field->add_subfields( '9', $authid ); + $field->add_subfields( $authsubfield, $authid ); $num_headings_changed++; $linker->update_cache($heading, $authid); $results{'added'}->{ $heading->display_form() }++; @@ -1635,6 +1638,7 @@ sub GetMarcSubjects { my $subject_limit = C4::Context->preference("TraceCompleteSubfields") ? 'su,complete-subfield' : 'su'; my $AuthoritySeparator = C4::Context->preference('AuthoritySeparator'); + my $authsubfield = Koha::Authorities->authority_linking_subfield; foreach my $field ( $record->field($fields_filter) ) { next unless ($field->tag() >= $mintag && $field->tag() <= $maxtag); @@ -1643,7 +1647,7 @@ sub GetMarcSubjects { my @link_loop; # if there is an authority link, build the links with an= subfield9 - my $subfield9 = $field->subfield('9'); + my $subfield9 = $field->subfield($authsubfield); my $authoritylink; if ($subfield9) { my $linkvalue = $subfield9; @@ -1654,7 +1658,7 @@ sub GetMarcSubjects { # other subfields for my $subject_subfield (@subfields) { - next if ( $subject_subfield->[0] eq '9' ); + next if ( $subject_subfield->[0] eq $authsubfield ); # don't load unimarc subfields 3,4,5 next if ( ( $marcflavour eq "UNIMARC" ) and ( $subject_subfield->[0] =~ /2|3|4|5/ ) ); @@ -1727,6 +1731,7 @@ sub GetMarcAuthors { my @marcauthors; my $AuthoritySeparator = C4::Context->preference('AuthoritySeparator'); + my $authsubfield = Koha::Authorities->authority_linking_subfield; foreach my $field ( $record->field($fields_filter) ) { next unless $field->tag() >= $mintag && $field->tag() <= $maxtag; @@ -1736,7 +1741,7 @@ sub GetMarcAuthors { my $count_auth = 0; # if there is an authority link, build the link with Koha-Auth-Number: subfield9 - my $subfield9 = $field->subfield('9'); + my $subfield9 = $field->subfield($authsubfield); if ($subfield9) { my $linkvalue = $subfield9; $linkvalue =~ s/(\(|\))//g; @@ -1746,7 +1751,7 @@ sub GetMarcAuthors { # other subfields my $unimarc3; for my $authors_subfield (@subfields) { - next if ( $authors_subfield->[0] eq '9' ); + next if ( $authors_subfield->[0] eq $authsubfield ); # unimarc3 contains the $3 of the author for UNIMARC. # For french academic libraries, it's the "ppn", and it's required for idref webservice @@ -1882,6 +1887,7 @@ sub GetMarcSeries { my @marcseries; my $AuthoritySeparator = C4::Context->preference('AuthoritySeparator'); + my $authsubfield = Koha::Authorities->authority_linking_subfield; foreach my $field ( $record->field($fields_filter) ) { next unless $field->tag() >= $mintag && $field->tag() <= $maxtag; @@ -1892,7 +1898,7 @@ sub GetMarcSeries { for my $series_subfield (@subfields) { # ignore $9, used for authority link - next if ( $series_subfield->[0] eq '9' ); + next if ( $series_subfield->[0] eq $authsubfield ); my $volume_number; my $code = $series_subfield->[0]; --- a/C4/Linker/Default.pm +++ a/C4/Linker/Default.pm @@ -22,6 +22,7 @@ use warnings; use Carp; use MARC::Field; use C4::Heading; +use Koha::Authorities; use base qw(C4::Linker); @@ -34,7 +35,8 @@ sub get_link { my $authid; my $fuzzy = 0; my $match_count; - + my $authsubfield = Koha::Authorities->authority_linking_subfield; + if ( $self->{'cache'}->{$search_form.$auth_type}->{'cached'} ) { $authid = $self->{'cache'}->{$search_form.$auth_type}->{'authid'}; $fuzzy = $self->{'cache'}->{$search_form.$auth_type}->{'fuzzy'}; @@ -59,7 +61,7 @@ sub get_link { if ( !defined $authid && $self->{'broader_headings'} ) { my $field = $heading->field(); - my @subfields = grep { $_->[0] ne '9' } $field->subfields(); + my @subfields = grep { $_->[0] ne $authsubfield } $field->subfields(); if ( scalar @subfields > 1 ) { pop @subfields; $field = --- a/C4/UsageStats.pm +++ a/C4/UsageStats.pm @@ -111,6 +111,7 @@ sub BuildReport { BiblioAddsAuthorities AuthorityMergeLimit AuthorityMergeMode + AuthoritySubfieldLink UseAuthoritiesForTracings CatalogModuleRelink hide_marc --- a/C4/XSLT.pm +++ a/C4/XSLT.pm @@ -173,7 +173,7 @@ sub get_xslt_sysprefs { TrackClicks opacthemes IdRef OpacSuppression OPACResultsLibrary OPACShowOpenURL OpenURLResolverURL OpenURLImageLocation - OpenURLText OPACShowMusicalInscripts OPACPlayMusicalInscripts / ) + OpenURLText OPACShowMusicalInscripts OPACPlayMusicalInscripts AuthoritySubfieldLink / ) { my $sp = C4::Context->preference( $syspref ); next unless defined($sp); --- a/Koha/Authorities.pm +++ a/Koha/Authorities.pm @@ -22,6 +22,7 @@ use Modern::Perl; use Carp; use Koha::Database; +use C4::Context; use Koha::Authority; @@ -94,6 +95,21 @@ sub linked_biblionumbers { return @biblionumbers; } +=head3 authority_linking_subfield + + $authsubfield = Koha::Authorities->authority_linking_subfield; + + Returns the authority subfield for selected MARC format + +=cut + +sub authority_linking_subfield { + my ( $class ) = @_; + + return C4::Context->preference('AuthoritySubfieldLink'); + +} + =head3 type =cut --- a/authorities/blinddetail-biblio-search.pl +++ a/authorities/blinddetail-biblio-search.pl @@ -57,6 +57,7 @@ my $authid = $query->param('authid'); my $index = $query->param('index'); my $tagid = $query->param('tagid'); my $relationship = $query->param('relationship'); +my $authsubfield = Koha::Authorities->authority_linking_subfield; # open template my ( $template, $loggedinuser, $cookie ) = get_template_and_user( @@ -87,7 +88,7 @@ if ($authid) { # Get all values for each distinct subfield and add to subfield loop my %done_subfields; for ( $field->subfields ) { - next if $_->[0] eq '9'; # $9 will be set with authid value + next if $_->[0] eq $authsubfield; # $9 will be set with authid value my $letter = $_->[0]; $letter ||= '@'; next if defined $done_subfields{$letter}; @@ -114,6 +115,7 @@ if ($authid) { $template->param( authid => $authid ? $authid : "", + authsubfield => $authsubfield, index => $index, tagid => $tagid, update_ind1 => defined($indicator1), --- a/authorities/detail.pl +++ a/authorities/detail.pl @@ -210,8 +210,9 @@ my $count = $authobj ? $authobj->get_usage_count : 0; my $sth = $dbh->prepare("select distinct tagfield from marc_subfield_structure where authtypecode=?"); $sth->execute($authtypecode); my $biblio_fields; +my $authsubfield = Koha::Authorities->authority_linking_subfield; while (my ($tagfield) = $sth->fetchrow) { - $biblio_fields.= $tagfield."9,"; + $biblio_fields.= $tagfield.$authsubfield.","; } chop $biblio_fields if $biblio_fields; --- a/cataloguing/addbiblio.pl +++ a/cataloguing/addbiblio.pl @@ -338,6 +338,7 @@ sub create_input { # it's an authorised field + my $authsubfield = Koha::Authorities->authority_linking_subfield; if ( $tagslib->{$tag}->{$subfield}->{authorised_value} ) { $subfield_data{marc_value} = build_authorized_values_list( $tag, $subfield, $value, $dbh, @@ -345,7 +346,7 @@ sub create_input { # it's a subfield $9 linking to an authority record - see bug 2206 } - elsif ($subfield eq "9" and + elsif ($subfield eq $authsubfield and exists($tagslib->{$tag}->{'a'}->{authtypecode}) and defined($tagslib->{$tag}->{'a'}->{authtypecode}) and $tagslib->{$tag}->{'a'}->{authtypecode} ne '') { @@ -516,6 +517,7 @@ sub build_tabs { if($max_num_tab >= 9){ $max_num_tab = 9; } + my $authsubfield = Koha::Authorities->authority_linking_subfield; # loop through each tab 0 through 9 for ( my $tabloop = 0 ; $tabloop <= $max_num_tab ; $tabloop++ ) { my @loop_data = (); #innerloop in the template. @@ -578,7 +580,7 @@ sub build_tabs { ); } } - + # now, loop again to add parameter subfield that are not in the MARC::Record foreach my $subfield ( sort( keys %{ $tagslib->{$tag} } ) ) { @@ -588,7 +590,7 @@ sub build_tabs { next if ( ( $tagslib->{$tag}->{$subfield}->{hidden} <= -4 ) or ( $tagslib->{$tag}->{$subfield}->{hidden} >= 5 ) ) - and not ( $subfield eq "9" and + and not ( $subfield eq $authsubfield and exists($tagslib->{$tag}->{'a'}->{authtypecode}) and defined($tagslib->{$tag}->{'a'}->{authtypecode}) and $tagslib->{$tag}->{'a'}->{authtypecode} ne "" @@ -638,7 +640,7 @@ sub build_tabs { next if ( ( $tagslib->{$tag}->{$subfield}->{hidden} <= -4 ) or ( $tagslib->{$tag}->{$subfield}->{hidden} >= 5 ) ) - and not ( $subfield eq "9" and + and not ( $subfield eq $authsubfield and exists($tagslib->{$tag}->{'a'}->{authtypecode}) and defined($tagslib->{$tag}->{'a'}->{authtypecode}) and $tagslib->{$tag}->{'a'}->{authtypecode} ne "" --- a/installer/data/mysql/atomicupdate/bug_17511.perl +++ a/installer/data/mysql/atomicupdate/bug_17511.perl @@ -0,0 +1,8 @@ +$DBversion = 'XXX'; # will be replaced by the RM +if( CheckVersion( $DBversion ) ) { + # you can use $dbh here like: + $dbh->do(q{INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES ('AuthoritySubfieldLink', '9', NULL, 'Define authority linking subfield. Note: if you change this you should change the value also from indexing configurations.', 'Free') }); + + # Always end with this (adjust the bug info) + NewVersion( $DBversion, 17511, "Change authority linking subfield from 9 to 0"); +} --- a/installer/data/mysql/mandatory/sysprefs.sql +++ a/installer/data/mysql/mandatory/sysprefs.sql @@ -67,6 +67,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('AuthorityMergeLimit','50',NULL,'Maximum number of biblio records updated immediately when an authority record has been modified.','integer'), ('AuthorityMergeMode','loose','loose|strict','Authority merge mode','Choice'), ('AuthoritySeparator','--','10','Used to separate a list of authorities in a display. Usually --','free'), +('AuthoritySubfieldLink','9',NULL,'Define authority linking subfield. Note: if you change this you should change the value also from indexing configurations.','Free'), ('AuthSuccessLog','',NULL,'If enabled, log successful authentications','YesNo'), ('autoBarcode','OFF','incremental|annual|hbyymmincr|EAN13|OFF','Used to autogenerate a barcode: incremental will be of the form 1, 2, 3; annual of the form 2007-0001, 2007-0002; hbyymmincr of the form HB08010001 where HB=Home Branch','Choice'), ('AutoCreateAuthorities','0',NULL,'Automatically create authorities that do not exist when cataloging records.','YesNo'), --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/authorities.pref +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/authorities.pref @@ -63,6 +63,11 @@ Authorities: "loose": loose "strict": strict - mode. In strict mode subfields that are not found in the authority record, are deleted. Loose mode will keep them. Loose mode is the historical behavior and still the default. + - + - "Define authority linking subfield." + - pref: AuthoritySubfieldLink + default: "9" + - Note: if you change this you should also change the value from indexing mappings. Linker: - --- a/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/blinddetail-biblio-search.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/blinddetail-biblio-search.tt @@ -42,6 +42,7 @@ [% ELSE %] var index_start = "[% index | html %]"; var whichfield; + var authsubfield = "[% authsubfield %]"; try { whichfield = opener.opener.document.getElementById(index_start); } catch(e) { @@ -136,7 +137,7 @@ [% IF ( clear ) %] if (subfield){subfield.value="" ;} [% ELSE %] - if(code.value=='9'){ + if(code.value==authsubfield){ subfield.value = "[% To.json(authid) | $raw %]"; break; } --- a/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slim2intranetDetail.xsl +++ a/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slim2intranetDetail.xsl @@ -28,6 +28,7 @@ + { @@ -153,6 +154,7 @@ abc au + @@ -162,12 +164,14 @@ + + @@ -195,6 +199,7 @@ /cgi-bin/koha/catalogue/search.pl + @@ -646,8 +651,8 @@ - - /cgi-bin/koha/catalogue/search.pl?q=an: + + /cgi-bin/koha/catalogue/search.pl?q=an: /cgi-bin/koha/catalogue/search.pl?q= @@ -705,8 +710,8 @@ - - /cgi-bin/koha/catalogue/search.pl?q=an: + + /cgi-bin/koha/catalogue/search.pl?q=an: /cgi-bin/koha/catalogue/search.pl?q= @@ -1459,6 +1464,7 @@ +
@@ -1471,8 +1477,8 @@ - - /cgi-bin/koha/catalogue/search.pl?q=an: + + /cgi-bin/koha/catalogue/search.pl?q=an: /cgi-bin/koha/catalogue/search.pl?q=au:"" --- a/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slim2intranetResults.xsl +++ a/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slim2intranetResults.xsl @@ -27,6 +27,7 @@ + @@ -353,8 +354,8 @@ - - /cgi-bin/koha/catalogue/search.pl?q=an: + + /cgi-bin/koha/catalogue/search.pl?q=an: /cgi-bin/koha/catalogue/search.pl?q=au:"" --- a/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slimUtils.xsl +++ a/koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slimUtils.xsl @@ -209,9 +209,9 @@ - + - /cgi-bin/koha/catalogue/search.pl?q=an: + /cgi-bin/koha/catalogue/search.pl?q=an: @@ -407,6 +407,7 @@ + Series: @@ -474,8 +475,8 @@ - - ?q=an: + + ?q=an: @@ -516,8 +517,8 @@ - - ?q=an: + + ?q=an: --- a/koha-tmpl/intranet-tmpl/prog/en/xslt/NORMARCslim2intranetDetail.xsl +++ a/koha-tmpl/intranet-tmpl/prog/en/xslt/NORMARCslim2intranetDetail.xsl @@ -23,6 +23,7 @@ ,complete-subfield + { @@ -105,8 +106,8 @@ - - /cgi-bin/koha/catalogue/search.pl?q=an: + + /cgi-bin/koha/catalogue/search.pl?q=an: /cgi-bin/koha/catalogue/search.pl?q=au: @@ -120,8 +121,8 @@ - - /cgi-bin/koha/catalogue/search.pl?q=an: + + /cgi-bin/koha/catalogue/search.pl?q=an: /cgi-bin/koha/catalogue/search.pl?q=au: @@ -134,8 +135,8 @@ - - /cgi-bin/koha/catalogue/search.pl?q=an: + + /cgi-bin/koha/catalogue/search.pl?q=an: /cgi-bin/koha/catalogue/search.pl?q=au: @@ -407,8 +408,8 @@ --- a/koha-tmpl/intranet-tmpl/prog/en/xslt/NORMARCslim2intranetResults.xsl +++ a/koha-tmpl/intranet-tmpl/prog/en/xslt/NORMARCslim2intranetResults.xsl @@ -27,6 +27,7 @@ + @@ -305,8 +306,8 @@ - - /cgi-bin/koha/catalogue/search.pl?q=an: + + /cgi-bin/koha/catalogue/search.pl?q=an: /cgi-bin/koha/catalogue/search.pl?q=au:"" @@ -320,8 +321,8 @@ - - /cgi-bin/koha/catalogue/search.pl?q=an: + + /cgi-bin/koha/catalogue/search.pl?q=an: /cgi-bin/koha/catalogue/search.pl?q=au:"" @@ -342,8 +343,8 @@ - - /cgi-bin/koha/catalogue/search.pl?q=an: + + /cgi-bin/koha/catalogue/search.pl?q=an: /cgi-bin/koha/catalogue/search.pl?q=au:"" --- a/koha-tmpl/intranet-tmpl/prog/en/xslt/NORMARCslimUtils.xsl +++ a/koha-tmpl/intranet-tmpl/prog/en/xslt/NORMARCslimUtils.xsl @@ -231,9 +231,9 @@ - + - /cgi-bin/koha/opac-search.pl?q=an: + /cgi-bin/koha/opac-search.pl?q=an: --- a/koha-tmpl/intranet-tmpl/prog/en/xslt/UNIMARCslim2intranetDetail.xsl +++ a/koha-tmpl/intranet-tmpl/prog/en/xslt/UNIMARCslim2intranetDetail.xsl @@ -16,6 +16,7 @@ + --- a/koha-tmpl/intranet-tmpl/prog/en/xslt/UNIMARCslim2intranetResults.xsl +++ a/koha-tmpl/intranet-tmpl/prog/en/xslt/UNIMARCslim2intranetResults.xsl @@ -18,6 +18,7 @@ + --- a/koha-tmpl/intranet-tmpl/prog/en/xslt/UNIMARCslimUtils.xsl +++ a/koha-tmpl/intranet-tmpl/prog/en/xslt/UNIMARCslimUtils.xsl @@ -255,8 +255,8 @@ - - /cgi-bin/koha/catalogue/search.pl?q=an: + + /cgi-bin/koha/catalogue/search.pl?q=an: /cgi-bin/koha/catalogue/search.pl?q=su: @@ -295,10 +295,10 @@ - + /cgi-bin/koha/catalogue/search.pl?q=an: - + --- a/koha-tmpl/opac-tmpl/bootstrap/en/xslt/MARC21slim2OPACDetail.xsl +++ a/koha-tmpl/opac-tmpl/bootstrap/en/xslt/MARC21slim2OPACDetail.xsl @@ -712,8 +712,8 @@ subject - - /cgi-bin/koha/opac-search.pl?q=an: + + /cgi-bin/koha/opac-search.pl?q=an: @@ -742,9 +742,9 @@ - + - /cgi-bin/koha/opac-authoritiesdetail.pl?authid= + /cgi-bin/koha/opac-authoritiesdetail.pl?authid= fa fa-search @@ -765,8 +765,8 @@ - - /cgi-bin/koha/opac-search.pl?q=an: + + /cgi-bin/koha/opac-search.pl?q=an: /cgi-bin/koha/opac-search.pl?q= @@ -788,10 +788,10 @@ -- - + - /cgi-bin/koha/opac-authoritiesdetail.pl?authid= + /cgi-bin/koha/opac-authoritiesdetail.pl?authid= fa fa-search @@ -1649,8 +1649,8 @@ - - /cgi-bin/koha/opac-search.pl?q=an:"" + + /cgi-bin/koha/opac-search.pl?q=an:"" /cgi-bin/koha/opac-search.pl?q=au:"" @@ -1882,9 +1882,9 @@ - + - /cgi-bin/koha/opac-authoritiesdetail.pl?authid= + /cgi-bin/koha/opac-authoritiesdetail.pl?authid= fa fa-search --- a/koha-tmpl/opac-tmpl/bootstrap/en/xslt/MARC21slimUtils.xsl +++ a/koha-tmpl/opac-tmpl/bootstrap/en/xslt/MARC21slimUtils.xsl @@ -206,9 +206,9 @@ - + - /cgi-bin/koha/opac-search.pl?q=an: + /cgi-bin/koha/opac-search.pl?q=an: @@ -438,8 +438,8 @@ - - ?q=an: + + ?q=an: @@ -480,8 +480,8 @@ - - ?q=an: + + ?q=an: --- a/koha-tmpl/opac-tmpl/bootstrap/en/xslt/NORMARCslim2OPACDetail.xsl +++ a/koha-tmpl/opac-tmpl/bootstrap/en/xslt/NORMARCslim2OPACDetail.xsl @@ -100,17 +100,17 @@ - - /cgi-bin/koha/opac-search.pl?q=an: + + /cgi-bin/koha/opac-search.pl?q=an: /cgi-bin/koha/opac-search.pl?q=au: - + - /cgi-bin/koha/opac-authoritiesdetail.pl?authid= + /cgi-bin/koha/opac-authoritiesdetail.pl?authid= /opac-tmpl//images/filefind.png vertical-align:middle @@ -126,17 +126,17 @@ - - /cgi-bin/koha/opac-search.pl?q=an: + + /cgi-bin/koha/opac-search.pl?q=an: /cgi-bin/koha/opac-search.pl?q=au: - + - /cgi-bin/koha/opac-authoritiesdetail.pl?authid= + /cgi-bin/koha/opac-authoritiesdetail.pl?authid= /opac-tmpl//images/filefind.png vertical-align:middle @@ -151,17 +151,17 @@ - - /cgi-bin/koha/opac-search.pl?q=an: + + /cgi-bin/koha/opac-search.pl?q=an: /cgi-bin/koha/opac-search.pl?q=au: - + - /cgi-bin/koha/opac-authoritiesdetail.pl?authid= + /cgi-bin/koha/opac-authoritiesdetail.pl?authid= /opac-tmpl//images/filefind.png vertical-align:middle @@ -436,8 +436,8 @@ @@ -463,9 +463,9 @@ - + - /cgi-bin/koha/opac-authoritiesdetail.pl?authid= + /cgi-bin/koha/opac-authoritiesdetail.pl?authid= /opac-tmpl//images/filefind.png vertical-align:middle --- a/koha-tmpl/opac-tmpl/bootstrap/en/xslt/NORMARCslimUtils.xsl +++ a/koha-tmpl/opac-tmpl/bootstrap/en/xslt/NORMARCslimUtils.xsl @@ -228,9 +228,9 @@ - + - /cgi-bin/koha/opac-search.pl?q=an: + /cgi-bin/koha/opac-search.pl?q=an: --- a/koha-tmpl/opac-tmpl/bootstrap/en/xslt/UNIMARCslimUtils.xsl +++ a/koha-tmpl/opac-tmpl/bootstrap/en/xslt/UNIMARCslimUtils.xsl @@ -241,13 +241,13 @@ - + - + - + , @@ -357,10 +357,10 @@ - + /cgi-bin/koha/opac-search.pl?q=an: - + @@ -374,7 +374,7 @@ - + --- a/misc/maintenance/batchAuthorityLinking.pl +++ a/misc/maintenance/batchAuthorityLinking.pl @@ -0,0 +1,274 @@ +#!/usr/bin/perl + +#----------------------------------- +# Copyright 2019 Koha-Suomi Oy +# +# 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 2 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 Getopt::Long; + +use C4::Context; +use C4::Biblio; +use C4::Record; +use MARC::Field; + +use Koha::Authorities; + +my ($help, $confirm, $verbose); +my $schema = 'MARC21'; +my $chunks = 500; +my $authsubfield = Koha::Authorities->authority_linking_subfield; +my $oldsubfield; + +GetOptions( + 'h|help' => \$help, + 'v|verbose:i' => \$verbose, + 'c|confirm' => \$confirm, + 's|schema:s' => \$schema, + 'o|oldsubfield:s' => \$oldsubfield, + 'chunks:i' => \$chunks, +); + +my $usage = << 'ENDUSAGE'; + +Changes authority linking subfield from $9 to $0 + + -h --help This nice help! + + -v --verbose More chatty output. + + -c --confirm Confirm that you want to mangle your bibliographic records + + -s --schema Select MARC schema, MARC21, UNIMARC or NORMARC. Default is MARC21 + + -o --oldsubfield Define old ayhtority linking subfield value + + --chunks Increase processed chunks + + +EXAMPLE: + +perl batchAuthorityLinking.pl -v -c +perl batchAuthorityLinking.pl -v -c -s NORMARC -o 9 +perl batchAuthorityLinking.pl -v --chunks 1000 + +ENDUSAGE + +if ($help) { + print $usage; + exit 0; +} + +our $marc21Authorityfields = { + '100' => 1, + '110' => 1, + '111' => 1, + '130' => 1, + '245' => 1, + '400' => 1, + '410' => 1, + '440' => 1, + '490' => 1, + '600' => 1, + '610' => 1, + '611' => 1, + '630' => 1, + '648' => 1, + '650' => 1, + '651' => 1, + '652' => 1, + '653' => 1, + '654' => 1, + '655' => 1, + '656' => 1, + '657' => 1, + '662' => 1, + '690' => 1, + '691' => 1, + '696' => 1, + '697' => 1, + '698' => 1, + '699' => 1, + '700' => 1, + '710' => 1, + '711' => 1, + '730' => 1, + '751' => 1, + '796' => 1, + '797' => 1, + '798' => 1, + '799' => 1, + '800' => 1, + '810' => 1, + '811' => 1, + '830' => 1, + '896' => 1, + '897' => 1, + '898' => 1, + '899' => 1 +}; + +our $normarcAuthorityfields = { + '100' => 1, + '110' => 1, + '111' => 1, + '130' => 1, + '245' => 1, + '440' => 1, + '490' => 1, + '600' => 1, + '610' => 1, + '611' => 1, + '630' => 1, + '650' => 1, + '651' => 1, + '652' => 1, + '653' => 1, + '654' => 1, + '655' => 1, + '656' => 1, + '657' => 1, + '690' => 1, + '700' => 1, + '710' => 1, + '711' => 1, + '730' => 1, + '800' => 1, + '810' => 1, + '811' => 1, + '830' => 1 +}; + +our $unimarcAuthorityfields = { + '500' => 1, + '501' => 1, + '503' => 1, + '510' => 1, + '512' => 1, + '513' => 1, + '514' => 1, + '515' => 1, + '516' => 1, + '517' => 1, + '518' => 1, + '519' => 1, + '520' => 1, + '530' => 1, + '531' => 1, + '532' => 1, + '540' => 1, + '541' => 1, + '545' => 1, + '560' => 1, + '600' => 1, + '601' => 1, + '602' => 1, + '604' => 1, + '605' => 1, + '606' => 1, + '607' => 1, + '608' => 1, + '610' => 1, + '615' => 1, + '616' => 1, + '617' => 1, + '620' => 1, + '621' => 1, + '700' => 1, + '701' => 1, + '702' => 1, + '710' => 1, + '711' => 1, + '712' => 1, + '716' => 1, + '720' => 1, + '721' => 1, + '722' => 1, + '730' => 1 +}; + +my $params = { + chunks => $chunks, + page => 1 +}; + + +my $pageCount = 1; +my $authorityfields; + +if ($schema eq 'NORMARC') { + $authorityfields = $normarcAuthorityfields; +} elsif ($schema eq 'UNIMARC') { + $authorityfields = $normarcAuthorityfields; +} else { + $authorityfields = $marc21Authorityfields; +} + + +while ($pageCount >= $params->{page}) { + my $biblios = biblios($params); + my $count = 0; + my $lastnumber = 0; + foreach my $biblio (@{$biblios}) { + my $record = C4::Record::marcxml2marc($biblio->{metadata}); + foreach my $field ($record->fields) { + my @subfield_data; + if ($authorityfields->{$field->tag}) { + if ($field->subfields) { + for my $subfield ($field->subfields) { + if ($subfield->[0] eq $oldsubfield) { + $subfield->[0] = $authsubfield; + print "Change $schema $oldsubfield field to $authsubfield from ".$biblio->{biblionumber}."\n" if (defined $verbose); + } + push @subfield_data, $subfield->[0], $subfield->[1]; + } + } + } + $field->replace_with(MARC::Field->new( + $field->tag(), $field->indicator(1), $field->indicator(2), + @subfield_data) + ) if @subfield_data; + } + my $frameworkcode = C4::Biblio::GetFrameworkCode( $biblio->{biblionumber} ); + C4::Biblio::ModBiblio($record, $biblio->{biblionumber}, $frameworkcode) if $confirm; + $count++; + $lastnumber = $biblio->{biblionumber}; + } + print "last processed biblio $lastnumber\n"; + print "$count biblios processed!\n"; + if ($count eq $params->{chunks}) { + $pageCount++; + $params->{page} = $pageCount; + } else { + $pageCount = 0; + } +} + +sub biblios { + my ($params) = @_; + print "Starting to change offset $params->{page}!\n"; + my $biblios = Koha::Biblio::Metadatas->search({format => 'marcxml', schema => $schema}, + { + page => $params->{page}, + rows => $params->{chunks} + } + )->unblessed; + + return $biblios; + +} --- a/t/db_dependent/Koha/Authorities.t +++ a/t/db_dependent/Koha/Authorities.t @@ -193,6 +193,29 @@ unimarc,*,ind1:auth2,ind2:auth1|); is( $auth->controlled_indicators({ biblio_tag => '456' })->{ind2}, '1', 'UNIMARC: Swapped ind1' ); }; +subtest 'Test linking subfield syspref' => sub { + plan tests => 4; + + t::lib::Mocks::mock_preference( 'AuthoritySubfieldLink', '9' ); + my $authsubfield = Koha::Authorities->authority_linking_subfield; + is( $authsubfield, '9', 'Authority subfield link is 9' ); + my $record = MARC::Record->new; + $record->append_fields( + MARC::Field->new( '110', '', '', $authsubfield => '202' ) + ); + is( $record->field('110')->subfield($authsubfield), '202', 'Subfield 9 value is 202' ); + + t::lib::Mocks::mock_preference( 'AuthoritySubfieldLink', '0' ); + $authsubfield = Koha::Authorities->authority_linking_subfield; + is( $authsubfield, '0', 'Authority subfield link is 0' ); + $record = MARC::Record->new; + $record->append_fields( + MARC::Field->new( '110', '', '', $authsubfield => '203' ) + ); + is( $record->field('110')->subfield($authsubfield), '203', 'Subfield 0 value is 203' ); + +}; + sub simple_search_compat { if( $search_compat_pars->[0] == 0 ) { return ( $search_compat_pars->[1], [], 0 ); @@ -205,6 +228,7 @@ sub simple_search_compat { } sub few_marcxml_records { + my ($authsubfield) = @_; return [ q| --