From 0012bfb0f2c388f8f37f61def53be4e4917d6050 Mon Sep 17 00:00:00 2001 From: Marcel de Rooy Date: Mon, 24 Jul 2017 19:09:17 +0200 Subject: [PATCH] [SIGNED-OFF] Bug 10306: Support for multiple mappings in koha2marclinks This actually refactors koha2marclinks.pl in order to support multiple mappings per kohafield. Instead of three separate mapping pages for biblio, biblioitems and items, the script now lists them together. This gives a complete overview of all mappings rightaway. Changes are applied immediately across all frameworks. Note: This report handles the Default mappings just like it did before. In this script Koha already considered them as authoritative, although other parts of Koha did not. Follow-up report 19096 makes Default mappings authoritative throughout all Koha. On each line two buttons are provided, Add and Remove, in order to add or remove an individual mapping. We do no longer provide a separate form with the names of MARC tags. Since this form is targeted for administrators, it should be enough to ask for a field tag and subfield code. Note: The mappings for biblionumber, biblioitemnumber and itemnumber are so vital that this form marks them as readonly. It is not recommended to change them. Test plan: [1] Add a mapping. Verify via Frameworks or mysql command line that the kohafield is saved to the other frameworks too. [2] Remove the mapping again. Check Frameworks or mysql cl again. [3] Test adding a second mapping. Map copyrightdate to 260c and 264c. And map biblioitems.place to 260a and 264a. [4] Edit biblio record 1: Put 1980 in 260c. Do not include 264c. Edit biblio record 2: Put 1990 in 264c. Do not include 260c. Edit biblio record 3: Put 2000 in both 260c and 264c. Put CityA in 260a and in 264a. Edit biblio record 4: Put 2010 in 260c, and 2015 in 264c (which you should refuse normally). Put CityA in 260a, and CityB in 264a. [5] Create a report that shows biblioitems.place and biblio.copyrightdate for those biblio records. Record 4 should have 2010 in copyrightdate (since TransformMarcToKoha picks the first year for copyrightdate). Record 3 should have place CityA; record 4 should have CityA | CityB. Note: The CityA | CityB example illustrates that we should add some additional handling in TransformMarcToKoha for multiple 264s. [6] Add these four biblio records to a new list. Sort by Year. With OPACXSLTListsDisplay==default, check if the order = 1,2,3,4. (The order is based on biblio.copyrightdate.) Note that (RDA) record 2 would be on top without this patch set, since copyrightdate would have been null. Signed-off-by: Josef Moravec --- admin/koha2marclinks.pl | 182 ++++++++------------- .../prog/en/modules/admin/koha2marclinks.tt | 124 +++++--------- 2 files changed, 106 insertions(+), 200 deletions(-) diff --git a/admin/koha2marclinks.pl b/admin/koha2marclinks.pl index d8fd569..d6f2b5f 100755 --- a/admin/koha2marclinks.pl +++ b/admin/koha2marclinks.pl @@ -1,6 +1,7 @@ #!/usr/bin/perl # Copyright 2000-2002 Katipo Communications +# Copyright 2017 Rijksmuseum # # This file is part of Koha. # @@ -17,21 +18,18 @@ # You should have received a copy of the GNU General Public License # along with Koha; if not, see . -use strict; -use warnings; -use C4::Output; -use C4::Auth; +use Modern::Perl; use CGI qw ( -utf8 ); -use C4::Context; -use C4::Biblio; +use Koha::Database; +use C4::Auth; +use C4::Biblio; +use C4::Output; +use Koha::BiblioFrameworks; +use Koha::Caches; +use Koha::MarcSubfieldStructures; my $input = new CGI; -my $tablename = $input->param('tablename'); -$tablename = "biblio" unless ($tablename); -my $kohafield = $input->param('kohafield'); -my $op = $input->param('op'); -my $script_name = 'koha2marclinks.pl'; my ( $template, $borrowernumber, $cookie ) = get_template_and_user ( { @@ -44,121 +42,71 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user ( } ); -if ($op) { - $template->param( - script_name => $script_name, - $op => 1 - ); # we show only the TMPL_VAR names $op -} -else { - $template->param( - script_name => $script_name, - else => 1 - ); # we show only the TMPL_VAR names $op - $op = q{}; -} - -my $dbh = C4::Context->dbh; +my $schema = Koha::Database->new->schema; my $cache = Koha::Caches->get_instance(); -################## ADD_FORM ################################## -# called by default. Used to create form to add or modify a record -if ( $op eq 'add_form' ) { - my $sth = - $dbh->prepare( -"select tagfield,tagsubfield,liblibrarian as lib,tab from marc_subfield_structure where kohafield=? AND frameworkcode=''" - ); - $sth->execute( $tablename . "." . $kohafield ); - my ( $defaulttagfield, $defaulttagsubfield, $defaultliblibrarian ) = - $sth->fetchrow; +# Update data before showing the form +my $no_upd; - for ( my $i = 0 ; $i <= 9 ; $i++ ) { - my $sth2 = - $dbh->prepare( -"select tagfield,tagsubfield,liblibrarian as lib,tab from marc_subfield_structure where tagfield like ? AND frameworkcode=''" - ); - $sth2->execute("$i%"); - my @marcarray; - push @marcarray, " "; - while ( my ( $field, $tagsubfield, $liblibrarian ) = - $sth2->fetchrow_array ) - { - push @marcarray, "$field $tagsubfield - $liblibrarian"; - } - my $marclist = { - values => \@marcarray, - default => "$defaulttagfield $defaulttagsubfield - $defaultliblibrarian", - }; - $template->param( "marclist$i" => $marclist ); - } - $template->param( - tablename => $tablename, - kohafield => $kohafield - ); +if( $input->param('add_field') ) { + # add a mapping to all frameworks + my ($kohafield, $tag, $sub) = split /,/, $input->param('add_field'), 3; + Koha::MarcSubfieldStructures->search({ tagfield => $tag, tagsubfield => $sub })->update({ kohafield => $kohafield }); - # END $OP eq ADD_FORM -################## ADD_VALIDATE ################################## - # called by add_form, used to insert/modify data in DB -} -elsif ( $op eq 'add_validate' ) { +} elsif( $input->param('remove_field') ) { + # remove a mapping from all frameworks + my ($tag, $sub) = split /,/, $input->param('remove_field'), 2; + Koha::MarcSubfieldStructures->search({ tagfield => $tag, tagsubfield => $sub })->update({ kohafield => undef }); - #----- empty koha field : - $dbh->do( -"update marc_subfield_structure set kohafield='' where kohafield='$tablename.$kohafield'" - ); +} else { + $no_upd = 1; +} - #---- reload if not empty - my @temp = split / /, $input->param('marc'); - $dbh->do( -"update marc_subfield_structure set kohafield='$tablename.$kohafield' where tagfield='$temp[0]' and tagsubfield='$temp[1]'" - ); - # We could get a list of all frameworks and do them one-by-one, or zap - # everything. - $cache->flush_all(); - print $input->redirect("/cgi-bin/koha/admin/koha2marclinks.pl?tablename=$tablename"); - exit; +# Clear the cache when needed +unless( $no_upd ) { + for( qw| default_value_for_mod_marc- MarcSubfieldStructure- | ) { + $cache->clear_from_cache($_); + } +} - # END $OP eq ADD_VALIDATE -################## DEFAULT ################################## +# Build/Show the form +my $dbix_map = { + # Koha to MARC mappings are found in only three tables + biblio => 'Biblio', + biblioitems => 'Biblioitem', + items => 'Item', +}; +my @cols; +foreach my $tbl ( sort keys %{$dbix_map} ) { + push @cols, + map { "$tbl.$_" } $schema->source( $dbix_map->{$tbl} )->columns; } -else { # DEFAULT - my $sth = - $dbh->prepare( -q|select tagfield,tagsubfield,liblibrarian,kohafield from marc_subfield_structure where kohafield is not NULL and kohafield != ''| - ); - $sth->execute; - my %fields; - while ( ( my $tagfield, my $tagsubfield, my $liblibrarian, my $kohafield ) = - $sth->fetchrow ) { - $fields{$kohafield}->{tagfield} = $tagfield; - $fields{$kohafield}->{tagsubfield} = $tagsubfield; - $fields{$kohafield}->{liblibrarian} = $liblibrarian; +my $kohafields = Koha::MarcSubfieldStructures->search({ + frameworkcode => q{}, + kohafield => { '>', '' }, +}); +my @loop_data; +foreach my $col ( @cols ) { + my $found; + my $readonly = $col =~ /\.(biblio|biblioitem|item)number$/; + foreach my $row ( $kohafields->search({ kohafield => $col }) ) { + $found = 1; + push @loop_data, { + kohafield => $col, + tagfield => $row->tagfield, + tagsubfield => $row->tagsubfield, + liblibrarian => $row->liblibrarian, + readonly => $readonly, + }; } + push @loop_data, { + kohafield => $col, + readonly => $readonly, + } if !$found; +} - #XXX: This might not work. Maybe should use a DBI call instead of SHOW COLUMNS - my $sth2 = $dbh->prepare("SHOW COLUMNS from $tablename"); - $sth2->execute; +$template->param( + loop => \@loop_data, +); - my @loop_data = (); - while ( ( my $field ) = $sth2->fetchrow_array ) { - my %row_data; # get a fresh hash for the row data - $row_data{tagfield} = $fields{ $tablename . "." . $field }->{tagfield}; - $row_data{tagsubfield} = - $fields{ $tablename . "." . $field }->{tagsubfield}; - $row_data{liblibrarian} = - $fields{ $tablename . "." . $field }->{liblibrarian}; - $row_data{kohafield} = $field; - $row_data{edit} = -"$script_name?op=add_form&tablename=$tablename&kohafield=$field"; - push( @loop_data, \%row_data ); - } - my $tablenames = { - values => [ 'biblio', 'biblioitems', 'items' ], - default => $tablename, - }; - $template->param( - loop => \@loop_data, - tablename => $tablenames, - ); -} #---- END $OP eq DEFAULT output_html_with_http_headers $input, $cookie, $template->output; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/koha2marclinks.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/koha2marclinks.tt index 1cf606a..32061a0 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/koha2marclinks.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/koha2marclinks.tt @@ -1,19 +1,27 @@ [% INCLUDE 'doc-head-open.inc' %] -Koha › Administration › -[% IF ( add_form ) %] Koha to MARC mapping › Connect [% tablename %].[% kohafield %] to a MARC subfield[% END %] -[% IF ( else ) %]Koha to MARC mapping [% tagfield %][% END %] +Koha › Administration › Koha to MARC mapping [% INCLUDE 'doc-head-close.inc' %] @@ -22,106 +30,56 @@ $(document).ready(function() { [% INCLUDE 'header.inc' %] [% INCLUDE 'prefs-admin-search.inc' %] - -[% IF ( add_form ) %] -
+ -
-
-
-[% ELSE %]
-[% END %] - -[% IF ( add_form ) %] -

Connect [% tablename %].[% kohafield %] to a MARC subfield

-

Choose and validate 1 MARC subfield for [% tablename %].[% kohafield %].

-

Note: All frameworks will be modified which is usually what you need, but you have been warned.

-
-
    - [% FOR i IN [ 0 .. 9 ] %] - [% marclist = "marclist$i" %] -
  1. -
    - - - - - - -
    -
  2. - [% END %] -
-
-
-
- - - - - -
- Cancel -
-[% END %] - -[% IF ( else ) %] +

Koha to MARC mapping

+
+
-

Koha to MARC mapping [% tagfield %]

- -

- -

-
- - +
+ - + + [% FOREACH loo IN loop %] - + - + + [% END %] +
Koha field Tag Subfield Lib  
[% loo.kohafield %][% loo.kohafield %] [% loo.tagfield %] [% loo.tagsubfield %] [% loo.liblibrarian %] Edit + [% IF !loo.readonly %] + Add + [% IF loo.tagfield %] Remove [% END %] + [% END %] +
-[% END %] + + + + +
-[% UNLESS ( add_form ) %] +
[% INCLUDE 'admin-menu.inc' %]
-[% END %] +
[% INCLUDE 'intranet-bottom.inc' %] -- 2.1.4