From 5d170aa26865ee308f9d44992ea9f8eb9c6e0c19 Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Fri, 29 Mar 2013 17:29:27 +0100 Subject: [PATCH] Bug 8015: Add unit tests for SimpleMARC and MarcModificationTemplates routines Signed-off-by: Kyle M Hall Bug 8015: Fix complains from qa tools Signed-off-by: Bernardo Gonzalez Kriegel Bug 8015: Get rid of the eval in ModifyRecordWithTemplate This patch removes the use of eval in the C4::MarcModificationTemplates::ModifyRecordWithTemplate routine. Now this routine call the wanted modification routine with the list of parameters. This call is done only if the condition is respected. Signed-off-by: Bernardo Gonzalez Kriegel Bug 8015: Get rid of eval for evaluating =~ m// Koha::SimpleMarc::field_equals uses eval in order to check if a string matches a pattern. Now this eval is removed and the "regex" variable does not contain the regex separated character (/ or |). Regression: Before this patch, the user was able to user a modifier. Now it is not possible. Signed-off-by: Bernardo Gonzalez Kriegel Bug 8015: Get rid of the eval for substitution Before this patch, the regex substitution was contain into only one variable (e.g. my $regex = "/foo/bar/i"). Now each member of the regex is stored into a field in the marc_modification_template_actions sql table. In order to avoid a complex code, only modifiers i and g are take into account. Note: If you already add the mmta table, you have to drop it. This patch also adds a foreign key from mmta to mmt tables. Signed-off-by: Bernardo Gonzalez Kriegel Bug 8015: FIX ui issue Signed-off-by: Bernardo Gonzalez Kriegel Bug 8015: The template name is a required field Test plan: Try to add a template with an empty string as name. Signed-off-by: Bernardo Gonzalez Kriegel Signed-off-by: Galen Charlton --- C4/Koha.pm | 2 +- C4/MarcModificationTemplates.pm | 249 ++++++++++------- Koha/SimpleMARC.pm | 92 +++--- installer/data/mysql/kohastructure.sql | 7 +- installer/data/mysql/updatedatabase.pl | 7 +- .../tools/marc_modification_templates.tt | 48 ++-- t/SimpleMARC.t | 199 +++++++++++++ t/db_dependent/MarcModificationTemplates.t | 262 ++++++++++++++++++ tools/marc_modification_templates.pl | 41 +-- 9 files changed, 704 insertions(+), 203 deletions(-) create mode 100644 t/SimpleMARC.t create mode 100644 t/db_dependent/MarcModificationTemplates.t diff --git a/C4/Koha.pm b/C4/Koha.pm index bb3efc7bc5..fe288d00d8 100644 --- a/C4/Koha.pm +++ b/C4/Koha.pm @@ -1498,7 +1498,7 @@ sub _isbn_cleanup { sub Log { my ($data) = @_; warn $data; - open my $fh, '>>/tmp/koha.log'; + open my $fh, '>>', '/tmp/koha.log'; print $fh "$data\n"; close $fh; } diff --git a/C4/MarcModificationTemplates.pm b/C4/MarcModificationTemplates.pm index 8c9212f13c..d26b76dd81 100644 --- a/C4/MarcModificationTemplates.pm +++ b/C4/MarcModificationTemplates.pm @@ -1,29 +1,28 @@ package C4::MarcModificationTemplates; -# Copyright 2010 Kyle M Hall -# # 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. +# Copyright 2010 Kyle M Hall +# +# 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. +# 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. +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . ## NOTE: ## Parts of this module are used from cgi scripts that are detached from apache before ## execution. For this reason, the C4::Koha::Log function has been used to capture ## output for debugging purposes. -use strict; -use warnings; +use Modern::Perl; use DateTime; @@ -128,7 +127,9 @@ sub AddModificationTemplate { $action->{'field_value'}, $action->{'to_field'}, $action->{'to_subfield'}, - $action->{'to_regex'}, + $action->{'to_regex_search'}, + $action->{'to_regex_replace'}, + $action->{'to_regex_modifiers'}, $action->{'conditional'}, $action->{'conditional_field'}, $action->{'conditional_subfield'}, @@ -156,9 +157,6 @@ sub DelModificationTemplate { my $dbh = C4::Context->dbh; my $sth = $dbh->prepare("DELETE FROM marc_modification_templates WHERE template_id = ?"); $sth->execute( $template_id ); - - $sth = $dbh->prepare("DELETE FROM marc_modification_template_actions WHERE template_id = ?"); - $sth->execute( $template_id ); } =head2 @@ -211,7 +209,7 @@ sub GetModificationTemplateActions { AddModificationTemplateAction( $template_id, $action, $field_number, $from_field, $from_subfield, $field_value, - $to_field, $to_subfield, $to_regex, + $to_field, $to_subfield, $to_regex_search, $to_regex_replace, $to_regex_modifiers $conditional, $conditional_field, $conditional_subfield, $conditional_comparison, $conditional_value, $conditional_regex, $description @@ -231,7 +229,9 @@ sub AddModificationTemplateAction { $field_value, $to_field, $to_subfield, - $to_regex, + $to_regex_search, + $to_regex_replace, + $to_regex_modifiers, $conditional, $conditional_field, $conditional_subfield, @@ -243,11 +243,11 @@ sub AddModificationTemplateAction { C4::Koha::Log( "C4::MarcModificationTemplates::AddModificationTemplateAction( $template_id, $action, $field_number, $from_field, $from_subfield, $field_value, $to_field, $to_subfield, - $to_regex, $conditional, $conditional_field, $conditional_subfield, $conditional_comparison, + $to_regex_search, $to_regex_replace, $to_regex_modifiers, $conditional, $conditional_field, $conditional_subfield, $conditional_comparison, $conditional_value, $conditional_regex, $description )" ) if DEBUG; warn( "C4::MarcModificationTemplates::AddModificationTemplateAction( $template_id, $action, $field_number, $from_field, $from_subfield, $field_value, $to_field, $to_subfield, - $to_regex, $conditional, $conditional_field, $conditional_subfield, $conditional_comparison, + $to_regex_search, $to_regex_replace, $to_regex_modifiers, $conditional, $conditional_field, $conditional_subfield, $conditional_comparison, $conditional_value, $conditional_regex, $description )" ) if DEBUG; $conditional_regex ||= '0'; @@ -270,7 +270,9 @@ sub AddModificationTemplateAction { field_value, to_field, to_subfield, - to_regex, + to_regex_search, + to_regex_replace, + to_regex_modifiers, conditional, conditional_field, conditional_subfield, @@ -279,7 +281,7 @@ sub AddModificationTemplateAction { conditional_regex, description ) - VALUES ( NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )"; + VALUES ( NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )"; $sth = $dbh->prepare( $query ); @@ -293,7 +295,9 @@ sub AddModificationTemplateAction { $field_value, $to_field, $to_subfield, - $to_regex, + $to_regex_search, + $to_regex_replace, + $to_regex_modifiers, $conditional, $conditional_field, $conditional_subfield, @@ -310,7 +314,7 @@ sub AddModificationTemplateAction { ModModificationTemplateAction( $mmta_id, $action, $field_number, $from_field, $from_subfield, $field_value, $to_field, - $to_subfield, $to_regex, $conditional, + $to_subfield, $to_regex_search, $to_regex_replace, $to_regex_modifiers, $conditional, $conditional_field, $conditional_subfield, $conditional_comparison, $conditional_value, $conditional_regex, $description @@ -330,7 +334,9 @@ sub ModModificationTemplateAction { $field_value, $to_field, $to_subfield, - $to_regex, + $to_regex_search, + $to_regex_replace, + $to_regex_modifiers, $conditional, $conditional_field, $conditional_subfield, @@ -351,7 +357,9 @@ sub ModModificationTemplateAction { field_value = ?, to_field = ?, to_subfield = ?, - to_regex = ?, + to_regex_search = ?, + to_regex_replace = ?, + to_regex_modifiers = ?, conditional = ?, conditional_field = ?, conditional_subfield = ?, @@ -371,7 +379,9 @@ sub ModModificationTemplateAction { $field_value, $to_field, $to_subfield, - $to_regex, + $to_regex_search, + $to_regex_replace, + $to_regex_modifiers, $conditional, $conditional_field, $conditional_subfield, @@ -493,82 +503,113 @@ sub ModifyRecordsWithTemplate { =cut sub ModifyRecordWithTemplate { - my ( $template_id, $record ) = @_; - C4::Koha::Log( "C4::MarcModificationTemplates::ModifyRecordWithTemplate( $template_id, $record )" ) if DEBUG; - warn( "C4::MarcModificationTemplates::ModifyRecordWithTemplate( $template_id, $record )" ) if DEBUG; - C4::Koha::Log( "Unmodified Record:\n" . $record->as_formatted() ) if DEBUG >= 10; - warn( "Unmodified Record:\n" . $record->as_formatted() ) if DEBUG >= 10; - - my $current_date = DateTime->now()->ymd(); - my $branchcode = C4::Context->userenv->{branch}; - - my @actions = GetModificationTemplateActions( $template_id ); - - foreach my $a ( @actions ) { - my $action = $a->{'action'}; - my $field_number = $a->{'field_number'}; - my $from_field = $a->{'from_field'}; - my $from_subfield = $a->{'from_subfield'}; - my $field_value = $a->{'field_value'}; - my $to_field = $a->{'to_field'}; - my $to_subfield = $a->{'to_subfield'}; - my $to_regex = $a->{'to_regex'}; - my $conditional = $a->{'conditional'}; - my $conditional_field = $a->{'conditional_field'}; - my $conditional_subfield = $a->{'conditional_subfield'}; - my $conditional_comparison = $a->{'conditional_comparison'}; - my $conditional_value = $a->{'conditional_value'}; - my $conditional_regex = $a->{'conditional_regex'}; - - my $eval = "$action( \$record, '$from_field', '$from_subfield', "; - - if ( $field_value ) { - C4::Koha::Log( "Field value before replacements: $field_value" ) if ( DEBUG >= 3 ); - warn( "Field value before replacements: $field_value" ) if ( DEBUG >= 3 ); - - $field_value =~ s/__CURRENTDATE__/$current_date/g; - $field_value =~ s/__BRANCHCODE__/$branchcode/g; - - $eval .= " undef, " if ( $action eq 'update_field' ); - $eval .= " '$field_value' "; - - C4::Koha::Log( "Field value after replacements: $field_value" ) if ( DEBUG >= 3 ); - warn( "Field value after replacements: $field_value" ) if ( DEBUG >= 3 ); - } elsif ( $to_field ) { - $eval .= " '$to_field', '$to_subfield', '$to_regex' "; - } - - $eval .= ", '$field_number' " if ( $field_number ); - $eval .= ') '; - - if ( $conditional ) { - $eval .= " $conditional ( "; - - if ( $conditional_comparison eq 'exists' ) { - $eval .= "field_exists( \$record, '$conditional_field', '$conditional_subfield' )"; - - } elsif ( $conditional_comparison eq 'not_exists' ) { - $eval .= "!field_exists( \$record, '$conditional_field', '$conditional_subfield' )"; - - } elsif ( $conditional_comparison eq 'equals' ) { - $eval .= "field_equals( \$record, '$conditional_value', '$conditional_field', '$conditional_subfield', '$conditional_regex' ) "; - - } elsif ( $conditional_comparison eq 'not_equals' ) { - $eval .= "!field_equals( \$record, '$conditional_value', '$conditional_field', '$conditional_subfield', '$conditional_regex' ) "; - } - - $eval .= " )"; + my ( $template_id, $record ) = @_; + C4::Koha::Log( "C4::MarcModificationTemplates::ModifyRecordWithTemplate( $template_id, $record )" ) if DEBUG; + warn( "C4::MarcModificationTemplates::ModifyRecordWithTemplate( $template_id, $record )" ) if DEBUG; + C4::Koha::Log( "Unmodified Record:\n" . $record->as_formatted() ) if DEBUG >= 10; + warn( "Unmodified Record:\n" . $record->as_formatted() ) if DEBUG >= 10; + + my $current_date = DateTime->now()->ymd(); + my $branchcode = C4::Context->userenv->{branch}; + + my @actions = GetModificationTemplateActions( $template_id ); + + foreach my $a ( @actions ) { + my $action = $a->{'action'}; + my $field_number = $a->{'field_number'}; + my $from_field = $a->{'from_field'}; + my $from_subfield = $a->{'from_subfield'}; + my $field_value = $a->{'field_value'}; + my $to_field = $a->{'to_field'}; + my $to_subfield = $a->{'to_subfield'}; + my $to_regex_search = $a->{'to_regex_search'}; + my $to_regex_replace = $a->{'to_regex_replace'}; + my $to_regex_modifiers = $a->{'to_regex_modifiers'}; + my $conditional = $a->{'conditional'}; + my $conditional_field = $a->{'conditional_field'}; + my $conditional_subfield = $a->{'conditional_subfield'}; + my $conditional_comparison = $a->{'conditional_comparison'}; + my $conditional_value = $a->{'conditional_value'}; + my $conditional_regex = $a->{'conditional_regex'}; + + if ( $field_value ) { + $field_value =~ s/__CURRENTDATE__/$current_date/g; + $field_value =~ s/__BRANCHCODE__/$branchcode/g; + } + + my @params = ( $record, $from_field, $from_subfield ); + if ( $action eq 'update_field' ) { + push @params, + ( $field_value + ? ( undef, $field_value ) + : () + ); + } else { + push @params, + ( $field_value + ? $field_value + : () + ); + } + push @params, ( + ( ( not $field_value and $to_field ) + ? ( $to_field, $to_subfield, { search => $to_regex_search, replace => $to_regex_replace, modifiers => $to_regex_modifiers} ) + : () ), + ( $field_number + ? $field_number + : () ) + ); + + my $do = 1; + if ( $conditional ) { + for ( $conditional_comparison ) { + when ( /^exists$/ ) { + my $exists = field_exists( $record, $conditional_field, $conditional_subfield ); + $do = $conditional eq 'if' + ? $exists + : not $exists; + } + when ( /^not_exists$/ ) { + my $exists = field_exists( $record, $conditional_field, $conditional_subfield ); + $do = $conditional eq 'if' + ? not $exists + : $exists; + } + when ( /^equals$/ ) { + my $equals = field_equals( $record, $conditional_value, $conditional_field, $conditional_subfield, $conditional_regex ); + $do = $conditional eq 'if' + ? $equals + : not $equals; + } + when ( /^not_equals$/ ) { + my $equals = field_equals( $record, $conditional_value, $conditional_field, $conditional_subfield, $conditional_regex ); + $do = $conditional eq 'if' + ? not $equals + : $equals; + } + } + } + + if ( $do ) { + for ( $action ) { + when ( /^copy_field$/ ) { + copy_field( @params ); + } + when ( /^update_field$/ ) { + update_field( @params ); + } + when ( /^move_field$/ ) { + move_field( @params ); + } + when ( /^delete_field$/ ) { + delete_field( @params ); + } + } + } + + C4::Koha::Log( $record->as_formatted() ) if DEBUG >= 10; + warn( $record->as_formatted() ) if DEBUG >= 10; } - - $eval .= ";"; - - C4::Koha::Log("eval $eval") if DEBUG >= 2; - warn("eval $eval") if DEBUG >= 2; - eval {$eval}; - C4::Koha::Log( $record->as_formatted() ) if DEBUG >= 10; - warn( $record->as_formatted() ) if DEBUG >= 10; - - } } 1; __END__ diff --git a/Koha/SimpleMARC.pm b/Koha/SimpleMARC.pm index f72fc2f54c..bd4c35e47e 100644 --- a/Koha/SimpleMARC.pm +++ b/Koha/SimpleMARC.pm @@ -2,8 +2,7 @@ package Koha::SimpleMARC; # Copyright 2009 Kyle M. Hall -use strict; -use warnings; +use Modern::Perl; #use MARC::Record; @@ -66,7 +65,7 @@ at your option, any later version of Perl 5 you may have available. Copies a value from one field to another. If a regular expression ( $regex ) is supplied, the value will be transformed by the given regex before being copied into the new field. - Example: $regex = 's/Old Text/Replacement Text/' + Example: $regex = { search => 'Old Text', replace => 'Replacement Text', modifiers => 'g' }; If $n is passed, copy_field will only copy the Nth field of the list of fields. E.g. $n = 1 will only use the first field's value, $n = 2 will use only the 2nd field's value. @@ -83,15 +82,33 @@ sub copy_field { @values = ( $values[$n-1] ) if ( $n ); C4::Koha::Log( "@values = read_field( $record, $fromFieldName, $fromSubfieldName )" ) if $debug >= 3; - if ( $regex ) { + if ( $regex and $regex->{search} ) { + $regex->{modifiers} //= q||; + my @available_modifiers = qw( i g ); + my $modifiers = q||; + for my $modifier ( split //, $regex->{modifiers} ) { + $modifiers .= $modifier + if grep {/$modifier/} @available_modifiers; + } foreach my $value ( @values ) { - C4::Koha::Log( "\$value =~ s$regex" ) if ( $debug >= 3 ); - eval "\$value =~ s$regex"; + C4::Koha::Log( "\$value =~ s/$regex->{search}/$regex->{replace}/$modifiers" ) if ( $debug >= 3 ); + for ( $modifiers ) { + when ( /^(ig|gi)$/ ) { + $value =~ s/$regex->{search}/$regex->{replace}/ig; + } + when ( /^i$/ ) { + $value =~ s/$regex->{search}/$regex->{replace}/i; + } + when ( /^g$/ ) { + $value =~ s/$regex->{search}/$regex->{replace}/g; + } + default { + $value =~ s/$regex->{search}/$regex->{replace}/; + } + } } } - update_field( $record, $toFieldName, $toSubfieldName, $dont_erase, @values ); - } =head2 update_field @@ -114,21 +131,18 @@ sub update_field { if ( ! ( $record && $fieldName ) ) { return; } - if ( @values eq 1 ) { - _update_repeatable_field_with_single_value( $record, $fieldName, $subfieldName, @values ); - return; - } - my $i = 0; my $field; if ( $subfieldName ) { if ( my @fields = $record->field( $fieldName ) ) { unless ( $dont_erase ) { + @values = ($values[0]) x scalar( @fields ) + if @values == 1; foreach my $field ( @fields ) { $field->update( "$subfieldName" => $values[$i++] ); } } - if ( $i <= scalar @values - 1 ) { + if ( $i <= scalar ( @values ) - 1 ) { foreach my $field ( @fields ) { foreach my $j ( $i .. scalar( @values ) - 1) { $field->add_subfields( "$subfieldName" => $values[$j] ); @@ -144,6 +158,8 @@ sub update_field { } } else { ## No subfield if ( my @fields = $record->field( $fieldName ) ) { + @values = ($values[0]) x scalar( @fields ) + if @values == 1; foreach my $field ( @fields ) { $field->update( $values[$i++] ); } @@ -221,7 +237,7 @@ sub field_exists { Returns true if the field equals the given value, false otherwise. If a regular expression ( $regex ) is supplied, the value will be compared using - the given regex. Example: $regex = 'm/sought_text/' + the given regex. Example: $regex = 'sought_text' If $n is passed, the Nth field of a repeatable series will be used for comparison. Set $n to 1 or leave empty for a non-repeatable field. @@ -239,8 +255,8 @@ sub field_equals { my $field_value = $field_values[$n-1]; if ( $regex ) { - C4::Koha::Log( "Testing '$field_value' =~ m$value" ) if $debug >= 3; - return eval "\$field_value =~ m$value"; + C4::Koha::Log( "Testing '$field_value' =~ m/$value/" ) if $debug >= 3; + return $field_value =~ m/$value/; } else { return $field_value eq $value; } @@ -262,7 +278,7 @@ sub field_equals { sub move_field { my ( $record, $fromFieldName, $fromSubfieldName, $toFieldName, $toSubfieldName, $regex, $n ) = @_; C4::Koha::Log( "C4::SimpleMARC::move_field( '$record', '$fromFieldName', '$fromSubfieldName', '$toFieldName', '$toSubfieldName', '$regex', '$n' )" ) if $debug; - copy_field( $record, $fromFieldName, $fromSubfieldName, $toFieldName, $toSubfieldName, $regex, $n , 1); + copy_field( $record, $fromFieldName, $fromSubfieldName, $toFieldName, $toSubfieldName, $regex, $n , 'dont_erase' ); delete_field( $record, $fromFieldName, $fromSubfieldName, $n ); } @@ -296,45 +312,5 @@ sub delete_field { } } -=head2 _update_repeatable_field_with_single_value - - _update_repeatable_field_with_single_value( $record, $fieldName, $subfieldName, $value ); - - Updates a repeatable field, giving all existing copies of that field the given value. - - This is an internal function, and thus is not exported. - -=cut - -sub _update_repeatable_field_with_single_value { - my ( $record, $fieldName, $subfieldName, $value ) = @_; - C4::Koha::Log( "C4::SimpleMARC::_update_repeatable_field_with_single_value( $record, $fieldName, $subfieldName, $value )" ) if $debug; - - if ( ! ( $record && $fieldName ) ) { return; } - - my $field; - if ( $subfieldName ) { - if ( my @fields = $record->field( $fieldName ) ) { - foreach my $field ( @fields ) { - $field->update( $subfieldName => $value ); - } - } else { - ## Field does not exist, create it. - $field = MARC::Field->new( $fieldName, undef, undef, $subfieldName => $value ); - $record->append_fields( $field ); - } - } else { ## No subfield - if ( my @fields = $record->field( $fieldName ) ) { - foreach my $field ( @fields ) { - $field->update( $value ); - } - } else { - ## Field does not exists, create it - $field = MARC::Field->new( $fieldName, $value ); - $record->append_fields( $field ); - } - } -} - 1; __END__ diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index f337a97fb0..fefc98501b 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -3373,7 +3373,9 @@ CREATE TABLE IF NOT EXISTS marc_modification_template_actions ( field_value varchar(100) DEFAULT NULL, to_field varchar(3) DEFAULT NULL, to_subfield varchar(1) DEFAULT NULL, - to_regex text, + to_regex_search text, + to_regex_replace text, + to_regex_modifiers varchar(8) DEFAULT '', conditional enum('if','unless') DEFAULT NULL, conditional_field varchar(3) DEFAULT NULL, conditional_subfield varchar(1) DEFAULT NULL, @@ -3381,7 +3383,8 @@ CREATE TABLE IF NOT EXISTS marc_modification_template_actions ( conditional_value text, conditional_regex tinyint(1) NOT NULL DEFAULT '0', description text, - PRIMARY KEY (mmta_id) + PRIMARY KEY (mmta_id), + CONSTRAINT `mmta_ibfk_1` FOREIGN KEY (`template_id`) REFERENCES `marc_modification_templates` (`template_id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 1af6a0fb45..85128f7ee5 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -7707,7 +7707,9 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { field_value varchar(100) default NULL, to_field varchar(3) default NULL, to_subfield varchar(1) default NULL, - to_regex text, + to_regex_search text, + to_regex_replace text, + to_regex_modifiers varchar(8) default '', conditional enum('if','unless') default NULL, conditional_field varchar(3) default NULL, conditional_subfield varchar(1) default NULL, @@ -7715,7 +7717,8 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { conditional_value text, conditional_regex tinyint(1) NOT NULL default '0', description text, - PRIMARY KEY (mmta_id) + PRIMARY KEY (mmta_id), + CONSTRAINT `mmta_ibfk_1` FOREIGN KEY (`template_id`) REFERENCES `marc_modification_templates` (`template_id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; "); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/marc_modification_templates.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/marc_modification_templates.tt index 00a6e84e8c..1003271373 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/marc_modification_templates.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/marc_modification_templates.tt @@ -9,6 +9,8 @@ $(document).ready(function() { $('#select_template').change(function() { $('#select_template').submit(); }); + $("span.match_regex_prefix" ).hide(); + $("span.match_regex_suffix" ).hide(); }); //]]> @@ -97,9 +99,11 @@ function onToFieldRegexChange( checkboxObj ) { function onConditionalRegexChange( checkboxObj ) { if ( checkboxObj.checked ) { - document.getElementById( 'match_regex_prefix' ).style.visibility='visible'; + $("span.match_regex_prefix" ).show(); + $("span.match_regex_suffix" ).show(); } else { - document.getElementById( 'match_regex_prefix' ).style.visibility='hidden'; + $("span.match_regex_prefix" ).hide(); + $("span.match_regex_suffix" ).hide(); } } @@ -145,7 +149,7 @@ var modaction_legend_innerhtml; var action_submit_value; function editAction( mmta_id, ordering, action, field_number, from_field, from_subfield, field_value, to_field, - to_subfield, to_regex, conditional, conditional_field, conditional_subfield, + to_subfield, to_regex_search, to_regex_replace, to_regex_modifiers, conditional, conditional_field, conditional_subfield, conditional_comparison, conditional_value, conditional_regex, description ) { document.getElementById('mmta_id').value = mmta_id; @@ -160,9 +164,11 @@ function editAction( mmta_id, ordering, action, field_number, from_field, from_s document.getElementById('field_value').value = field_value; document.getElementById('to_field').value = to_field; document.getElementById('to_subfield').value = to_subfield; - document.getElementById('to_regex').value = to_regex; + $("#to_regex_search").val(to_regex_search); + $("#to_regex_replace").val(to_regex_replace); + $("#to_regex_modifiers").val(to_regex_modifiers); - document.getElementById('to_field_regex').checked = to_regex.length; + document.getElementById('to_field_regex').checked = conditional_regex.length; document.getElementById('to_field_regex').onchange(); setSelectByValue( 'conditional', conditional ); @@ -200,7 +206,9 @@ function cancelEditAction() { document.getElementById('field_value').value = ''; document.getElementById('to_field').value = ''; document.getElementById('to_subfield').value = ''; - document.getElementById('to_regex').value = ''; + $("#to_regex_search").val(""); + $("#to_regex_replace").val(""); + $("#to_regex_modifiers").val(""); document.getElementById('to_field_regex').checked = false; document.getElementById('to_field_regex').onchange(); @@ -245,6 +253,7 @@ function setSelectByValue( selectId, value ) {
+

MARC modification templates

@@ -290,19 +299,19 @@ function setSelectByValue( selectId, value ) { - Go up + Go up - Go top + Go top - Go bottom + Go bottom - Go down + Go down @@ -330,8 +339,8 @@ function setSelectByValue( selectId, value ) { [% IF ( ActionsLoo.to_field ) %] to [% ActionsLoo.to_field %][% IF ( ActionsLoo.to_subfield ) %]$[% ActionsLoo.to_subfield %][% END %] - [% IF ( ActionsLoo.to_regex ) %] - using RegEx s[% ActionsLoo.to_regex %] + [% IF ( ActionsLoo.to_regex_search ) %] + using RegEx s/[% ActionsLoo.to_regex_search %]/[% ActionsLoo.to_regex_replace %]/[% ActionsLoo.to_regex_modifiers %] [% END %] [% END %] @@ -346,7 +355,7 @@ function setSelectByValue( selectId, value ) { [% IF ( ActionsLoo.conditional_comparison_equals ) %] matches [% END %] [% IF ( ActionsLoo.conditional_comparison_not_equals ) %] does not match [% END %] - [% IF ( ActionsLoo.conditional_regex ) %] RegEx m[% END %][% ActionsLoo.conditional_value %] + [% IF ( ActionsLoo.conditional_regex ) %] RegEx m/[% END %][% ActionsLoo.conditional_value %]/ [% END %] [% ActionsLoo.description %] @@ -360,7 +369,9 @@ function setSelectByValue( selectId, value ) { "[% ActionsLoo.field_value |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]", "[% ActionsLoo.to_field |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]", "[% ActionsLoo.to_subfield |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]", - "[% ActionsLoo.to_regex |replace('\\\\', '\\\\') |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]", + "[% ActionsLoo.to_regex_search |replace('\\\\', '\\\\') |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]", + "[% ActionsLoo.to_regex_replace |replace('\\\\', '\\\\') |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]", + "[% ActionsLoo.to_regex_modifiers |replace('\\\\', '\\\\') |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]", "[% ActionsLoo.conditional |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]", "[% ActionsLoo.conditional_field |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]", "[% ActionsLoo.conditional_subfield |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]", @@ -411,7 +422,7 @@ function setSelectByValue( selectId, value ) { @@ -438,7 +449,7 @@ function setSelectByValue( selectId, value ) {
[% INCLUDE 'intranet-bottom.inc' %] diff --git a/t/SimpleMARC.t b/t/SimpleMARC.t new file mode 100644 index 0000000000..2969bd2f94 --- /dev/null +++ b/t/SimpleMARC.t @@ -0,0 +1,199 @@ +use Modern::Perl; + +use Test::More tests => 37; + +use_ok("MARC::Field"); +use_ok("MARC::Record"); +use_ok("Koha::SimpleMARC"); + +sub new_record { + my $record = MARC::Record->new; + $record->leader('03174nam a2200445 a 4500'); + my @fields = ( + MARC::Field->new( + 100, '1', ' ', + a => 'Knuth, Donald Ervin', + d => '1938', + ), + MARC::Field->new( + 245, '1', '4', + a => 'The art of computer programming', + c => 'Donald E. Knuth.', + ), + MARC::Field->new( + 650, ' ', '0', + a => 'Computer programming.', + 9 => '462', + ), + MARC::Field->new( + 952, ' ', ' ', + p => '3010023917', + y => 'BK', + c => 'GEN', + d => '2001-06-25', + ), + ); + $record->append_fields(@fields); + return $record; +} + +my $record = new_record; + +# field_exists +is( field_exists( $record, '650', 'a'), 'Computer programming.', '650$a exists' ); +is( field_exists( $record, '650', 'b'), undef, '650$b does not exist' ); + +$record->append_fields( + MARC::Field->new( + 650, ' ', '0', + a => 'Computer algorithms.', + 9 => '463', + ) +); + +is( field_exists( $record, '650', 'a'), 'Computer programming.', '650$a exists, field_exists returns the first one' ); + +# read_field +my @fields_650a = read_field( $record, '650', 'a'); +is( $fields_650a[0], 'Computer programming.', 'first 650$a' ); +is( $fields_650a[1], 'Computer algorithms.', 'second 650$a' ); +is( read_field( $record, '650', 'a', 1 ), 'Computer programming.', 'first 650$a bis' ); +is( read_field( $record, '650', 'a', 2 ), 'Computer algorithms.', 'second 650$a bis' ); +is( read_field( $record, '650', 'a', 3 ), undef, 'There is no 3 650$a' ); + +# copy_field +copy_field( $record, '245', 'a', '246', 'a' ); +is_deeply( read_field( $record, '245', 'a' ), 'The art of computer programming', 'After copy 245$a still exists' ); +is_deeply( read_field( $record, '246', 'a' ), 'The art of computer programming', '246$a is a new field' ); +delete_field( $record, '246' ); +is( field_exists( $record, '246', 'a', '246$a does not exist anymore' ), undef ); + +copy_field( $record, '650', 'a', '651', 'a' ); +my @fields_651a = read_field( $record, '651', 'a' ); +is_deeply( \@fields_651a, ['Computer programming.', 'Computer algorithms.'], 'Copy multivalued field' ); +delete_field( $record, '651' ); + +copy_field( $record, '650', 'a', '651', 'a', undef, 1 ); +@fields_651a = read_field( $record, '651', 'a' ); +is_deeply( read_field( $record, '651', 'a' ), 'Computer programming.', 'Copy first field 650$a' ); +delete_field( $record, '651' ); + +copy_field( $record, '650', 'a', '651', 'a', undef, 2 ); +@fields_651a = read_field( $record, '651', 'a' ); +is_deeply( read_field( $record, '651', 'a' ), 'Computer algorithms.', 'Copy second field 650$a' ); +delete_field( $record, '651' ); + +copy_field( $record, '650', 'a', '651', 'a', { search => 'Computer', replace => 'The art of' } ); +@fields_651a = read_field( $record, '651', 'a' ); +is_deeply( \@fields_651a, ['The art of programming.', 'The art of algorithms.'], 'Copy field using regex' ); + +copy_field( $record, '650', 'a', '651', 'a', { search => 'Computer', replace => 'The mistake of' } ); +@fields_651a = read_field( $record, '651', 'a' ); +is_deeply( \@fields_651a, ['The mistake of programming.', 'The mistake of algorithms.'], 'Copy fields using regex on existing fields' ); +delete_field( $record, '651' ); + +copy_field( $record, '650', 'a', '651', 'a', { search => 'Computer', replace => 'The art of' } ); +copy_field( $record, '650', 'a', '651', 'a', { search => 'Computer', replace => 'The mistake of' }, 1, "dont_erase" ); +@fields_651a = read_field( $record, '651', 'a' ); +is_deeply( \@fields_651a, [ + 'The art of programming.', + 'The mistake of programming.', + 'The art of algorithms.', + 'The mistake of programming.' +], 'Copy first field using regex on existing fields without erase existing values' ); +delete_field( $record, '651' ); + +copy_field( $record, '650', 'a', '651', 'a', { search => 'Computer', replace => 'The art of' } ); +copy_field( $record, '650', 'a', '651', 'a', { search => 'Computer', replace => 'The mistake of' }, undef , "dont_erase" ); +@fields_651a = read_field( $record, '651', 'a' ); +is_deeply( \@fields_651a, [ + 'The art of programming.', + 'The mistake of programming.', + 'The mistake of algorithms.', + 'The art of algorithms.', + 'The mistake of programming.', + 'The mistake of algorithms.' +], 'Copy fields using regex on existing fields without erase existing values' ); +delete_field( $record, '651' ); + +# Copy with regex modifiers +copy_field( $record, '650', 'a', '652', 'a', { search => 'o', replace => 'foo' } ); +my @fields_652a = read_field( $record, '652', 'a' ); +is_deeply( \@fields_652a, ['Cfoomputer programming.', 'Cfoomputer algorithms.'], 'Copy field using regex' ); + +copy_field( $record, '650', 'a', '653', 'a', { search => 'o', replace => 'foo', modifiers => 'g' } ); +my @fields_653a = read_field( $record, '653', 'a' ); +is_deeply( \@fields_653a, ['Cfoomputer prfoogramming.', 'Cfoomputer algfoorithms.'], 'Copy field using regex' ); + +copy_field( $record, '650', 'a', '654', 'a', { search => 'O', replace => 'foo', modifiers => 'i' } ); +my @fields_654a = read_field( $record, '654', 'a' ); +is_deeply( \@fields_654a, ['Cfoomputer programming.', 'Cfoomputer algorithms.'], 'Copy field using regex' ); + +copy_field( $record, '650', 'a', '655', 'a', { search => 'O', replace => 'foo', modifiers => 'gi' } ); +my @fields_655a = read_field( $record, '655', 'a' ); +is_deeply( \@fields_655a, ['Cfoomputer prfoogramming.', 'Cfoomputer algfoorithms.'], 'Copy field using regex' ); + +# update_field +update_field( $record, '952', 'p', undef, '3010023918' ); +is_deeply( read_field( $record, '952', 'p' ), '3010023918', 'update existing subfield 952$p' ); +delete_field( $record, '952' ); +update_field( $record, '952', 'p', undef, '3010023918' ); +update_field( $record, '952', 'y', undef, 'BK' ); +is_deeply( read_field( $record, '952', 'p' ), '3010023918', 'create subfield 952$p' ); +is_deeply( read_field( $record, '952', 'y' ), 'BK', 'create subfield 952$k on existing 952 field' ); +$record->append_fields( + MARC::Field->new( + 952, ' ', ' ', + p => '3010023917', + y => 'BK', + ), +); +update_field( $record, '952', 'p', undef, '3010023919' ); +my @fields_952p = read_field( $record, '952', 'p' ); +is_deeply( \@fields_952p, ['3010023919', '3010023919'], 'update all subfields 952$p with the same value' ); + +update_field( $record, '952', 'p', undef, ('3010023917', '3010023918') ); +@fields_952p = read_field( $record, '952', 'p' ); +is_deeply( \@fields_952p, ['3010023917', '3010023918'], 'update all subfields 952$p with the different values' ); + +# move_field +$record = new_record; +my ( @fields_952d, @fields_952c, @fields_954c, @fields_954p); +$record->append_fields( + MARC::Field->new( + 952, ' ', ' ', + p => '3010023917', + y => 'BK', + ), +); +copy_field( $record, '952', 'd', '952', 'd' ); +@fields_952d = read_field( $record, '952', 'd' ); +is_deeply( \@fields_952d, ['2001-06-25', '2001-06-25'], 'copy 952$d into others 952 field' ); + +move_field( $record, '952', 'c', '954', 'c' ); +@fields_952c = read_field( $record, '952', 'c' ); +@fields_954c = read_field( $record, '954', 'c' ); +is_deeply( \@fields_952c, [], 'The 952$c has moved' ); +is_deeply( \@fields_954c, ['GEN'], 'Now 954$c exists' ); + +move_field( $record, '952', 'p', '954', 'p', undef, 1 ); # Move the first field +@fields_952p = read_field( $record, '952', 'p' ); +@fields_954p = read_field( $record, '954', 'p' ); +is_deeply( \@fields_952p, ['3010023917'], 'One of 952$p has moved' ); +is_deeply( \@fields_954p, ['3010023917'], 'Now 954$p exists' ); + +$record = new_record; +$record->append_fields( + MARC::Field->new( + 952, ' ', ' ', + p => '3010023917', + y => 'BK', + ), +); + +move_field( $record, '952', 'p', '954', 'p' ); # Move all field +@fields_952p = read_field( $record, '952', 'p' ); +@fields_954p = read_field( $record, '954', 'p' ); +is_deeply( \@fields_952p, [], 'All 952$p have moved' ); +is_deeply( \@fields_954p, ['3010023917', '3010023917'], 'Now 2 954$p exist' ); + diff --git a/t/db_dependent/MarcModificationTemplates.t b/t/db_dependent/MarcModificationTemplates.t new file mode 100644 index 0000000000..04ff80ad92 --- /dev/null +++ b/t/db_dependent/MarcModificationTemplates.t @@ -0,0 +1,262 @@ +use Modern::Perl; + +use Test::More tests => 74; + +use_ok("MARC::Field"); +use_ok("MARC::Record"); +use_ok("C4::MarcModificationTemplates"); + +my $dbh = C4::Context->dbh; +$dbh->{AutoCommit} = 0; +$dbh->{RaiseError} = 1; + +$dbh->do(q|DELETE FROM marc_modification_templates|); + +# Creation +my $template_id = AddModificationTemplate("template_name"); +like( $template_id, qr|^\d+$|, "new template returns an id" ); + +is( AddModificationTemplateAction( + $template_id, 'move_field', 1, + '464', 'u', '', '464', '3', + '', '', '', + '', '', '', '', '', '', + 'move first 464$u to 464$3' +), 1, "Add first action"); + +is( AddModificationTemplateAction( + $template_id, 'update_field', 0, + '099', 't', 'LIV', '', '', + '', '', '', + 'if', '200', 'b', 'equals', 'Text', '', + 'Update field 099$t with value LIV if 200$b matches "Text"' +), 1, "Add second action"); + +is( AddModificationTemplateAction( + $template_id, 'copy_field', 0, + '606', 'a', '', '607', 'a', + '', '', '', + 'unless', '606', 'a', 'not_equals', '^AJAX', '1', + 'Copy field 606$a to 607$a unless 606$a matches RegEx m^AJAX' +), 1, "Add third action"); + +# Getter +my @actions = GetModificationTemplateActions( $template_id ); +is( @actions, 3, "3 actions are insered"); + +for my $action ( @actions ) { + isnt( GetModificationTemplateAction( $action->{mmta_id} ), undef, "action with id $action->{mmta_id} exists" ); +} + +my $first_action = $actions[0]; +is( $first_action->{ordering}, 1, "test ordering for first action" ); +is( $first_action->{action}, 'move_field', "test action for first action" ); +is( $first_action->{from_field}, '464', "test from_field for first action" ); +is( $first_action->{from_subfield}, 'u', "test from_subfield for first action" ); +is( $first_action->{to_field}, '464', "test to_field for first action" ); +is( $first_action->{to_subfield}, '3', "test to_subfield for first action" ); + +my $second_action = $actions[1]; +is( $second_action->{ordering}, 2, "test ordering for second action" ); +is( $second_action->{action}, 'update_field', "test action for second action" ); +is( $second_action->{from_field}, '099',"test from_field for second action" ); +is( $second_action->{from_subfield}, 't', "test from_subfield for second action" ); +is( $second_action->{field_value}, 'LIV', "test firld_value for second action" ); +is( $second_action->{to_field}, '', "test to_field for second action" ); +is( $second_action->{to_subfield}, '', "test to_subfield for second action" ); +is( $second_action->{conditional}, 'if', "test conditional for second action" ); +is( $second_action->{conditional_field}, '200', "test conditional_field for second action" ); +is( $second_action->{conditional_subfield}, 'b', "test conditional_subfield for second action" ); +is( $second_action->{conditional_comparison}, 'equals', "test conditional_comparison for second action" ); + +my $third_action = $actions[2]; +is( $third_action->{ordering}, 3, "test ordering for third action" ); +is( $third_action->{action}, 'copy_field', "test factionor third action" ); +is( $third_action->{from_field}, '606', "test from_field for third action" ); +is( $third_action->{from_subfield}, 'a', "test from_subfield for third action" ); +is( $third_action->{to_field}, '607', "test to_field for third action" ); +is( $third_action->{to_subfield}, 'a', "test to_subfield for third action" ); +is( $third_action->{conditional}, 'unless', "test conditional for third action" ); +is( $third_action->{conditional_field}, '606', "test conditional_field for third action" ); +is( $third_action->{conditional_subfield}, 'a', "test conditional_subfield for third action" ); +is( $third_action->{conditional_comparison}, 'not_equals', "test conditional_comparison for third action" ); +is( $third_action->{conditional_value}, '^AJAX', "test conditional_value for third action" ); + + +# Modifications +is( ModModificationTemplateAction( + $actions[1]->{mmta_id}, 'update_field', 0, + '100', 'u', 'LIV', '', '', + '', '', '', + 'if', '200', 'c', 'equals', 'Text', '', + 'Update field 099$t with value LIV if 200$b matches "Text"' +), 1, "Modify second action"); + +$second_action = GetModificationTemplateAction( $actions[1]->{mmta_id} ); +is( $second_action->{ordering}, 2, "test ordering for second action modified" ); +is( $second_action->{action}, 'update_field', "test action for second action modified" ); +is( $second_action->{from_field}, '100',"test from_field for second action modified" ); +is( $second_action->{from_subfield}, 'u', "test from_subfield for second action modified" ); +is( $second_action->{field_value}, 'LIV', "test firld_value for second action modified" ); +is( $second_action->{to_field}, '', "test to_field for second action modified" ); +is( $second_action->{to_subfield}, '', "test to_subfield for second action modified" ); +is( $second_action->{conditional}, 'if', "test conditional for second action modified" ); +is( $second_action->{conditional_field}, '200', "test conditional_field for second action modified" ); +is( $second_action->{conditional_subfield}, 'c', "test conditional_subfield for second action modified" ); +is( $second_action->{conditional_comparison}, 'equals', "test conditional_comparison for second action modified" ); + +# Up and down +is( MoveModificationTemplateAction( $actions[2]->{mmta_id}, 'top' ), '1', 'Move the third action on top' ); +is( MoveModificationTemplateAction( $actions[0]->{mmta_id}, 'bottom' ), '1', 'Move the first action on bottom' ); + +is( GetModificationTemplateAction( $actions[0]->{mmta_id} )->{ordering}, '3', 'First becomes third' ); +is( GetModificationTemplateAction( $actions[1]->{mmta_id} )->{ordering}, '2', 'Second stays second' ); +is( GetModificationTemplateAction( $actions[2]->{mmta_id} )->{ordering}, '1', 'Third becomes first' ); + +is( MoveModificationTemplateAction( $actions[0]->{mmta_id}, 'up' ), '1', 'Move up the first action (was third)' ); +is( MoveModificationTemplateAction( $actions[0]->{mmta_id}, 'up' ), '1', 'Move up the first action (was second)' ); +is( MoveModificationTemplateAction( $actions[2]->{mmta_id}, 'down' ), '1', 'Move down the third action (was second)' ); + +is( GetModificationTemplateAction( $actions[0]->{mmta_id} )->{ordering}, '1', 'First becomes again first' ); +is( GetModificationTemplateAction( $actions[1]->{mmta_id} )->{ordering}, '2', 'Second stays again second' ); +is( GetModificationTemplateAction( $actions[2]->{mmta_id} )->{ordering}, '3', 'Third becomes again third' ); + +# Cleaning +is( DelModificationTemplateAction( $actions[0]->{mmta_id} ), 2, "Delete the first action, 2 others are reordered" ); +is( GetModificationTemplateAction( $actions[0]->{mmta_id} ), undef, "first action does not exist anymore" ); + +is( DelModificationTemplate( $template_id ), 1, "The template has been deleted" ); + +is( GetModificationTemplateAction( $actions[1]->{mmta_id} ), undef, "second action does not exist anymore" ); +is( GetModificationTemplateAction( $actions[2]->{mmta_id} ), undef, "third action does not exist anymore" ); + +is( GetModificationTemplateActions( $template_id ), 0, "There is no action for deleted template" ); + +# ModifyRecordWithTemplate +my @USERENV = ( + 1, + 'test', + 'MASTERTEST', + 'Test', + 'Test', + 't', + 'Test', + 0, +); +C4::Context->_new_userenv ('DUMMY_SESSION_ID'); +C4::Context->set_userenv ( @USERENV ); + +$template_id = AddModificationTemplate("template_name"); +like( $template_id, qr|^\d+$|, "new template returns an id" ); + +is( AddModificationTemplateAction( + $template_id, 'copy_field', 0, + '245', 'a', '', '246', 'a', + '', '', '', + '', '', '', '', '', '', + 'copy field 245$a to 246$a' +), 1, 'Add first action: copy 245$a to 246$a'); + +is( AddModificationTemplateAction( + $template_id, 'delete_field', 0, + '650', 'a', '', '', '', + '', '', '', + 'if', '650', '9', 'equals', '462', '', + 'Delete field 650$a if 650$9=462' +), 1, 'Add second action: delete field 650$a if 650$9=462'); + +is( AddModificationTemplateAction( + $template_id, 'update_field', 0, + '952', 'p', '3010023917_updated', '', '', + '', '', '', + 'unless', '650', '9', 'equals', '42', '', + 'Update field 952$p with "3010023917_updated" if 650$9 != 42' +), 1, 'Add third action: update field 952$p with "3010023917_updated" if 650$9 != 42'); + +is( AddModificationTemplateAction( + $template_id, 'move_field', 0, + '952', 'd', '', '952', 'e', '', + '', '', '', + 'if', '952', 'c', 'equals', '^GEN', '1', + 'Move field 952$d to 952$e if 952$c =~ /^GE/' +), 1, 'Add fourth action: move field 952$d to 952$e if 952$c =~ /^GE/'); + +my $record = new_record(); + +ModifyRecordWithTemplate( $template_id, $record ); + +my $expected_record = expected_record(); +is_deeply( $record, $expected_record ); + +done_testing; + +sub new_record { + my $record = MARC::Record->new; + $record->leader('03174nam a2200445 a 4500'); + my @fields = ( + MARC::Field->new( + 100, '1', ' ', + a => 'Knuth, Donald Ervin', + d => '1938', + ), + MARC::Field->new( + 245, '1', '4', + a => 'The art of computer programming', + c => 'Donald E. Knuth.', + ), + MARC::Field->new( + 650, ' ', '0', + a => 'Computer programming.', + 9 => '462', + ), + MARC::Field->new( + 952, ' ', ' ', + p => '3010023917', + y => 'BK', + c => 'GEN', + d => '2001-06-25', + ), + ); + $record->append_fields(@fields); + return $record; +} + +sub expected_record { + my $record = MARC::Record->new; + $record->leader('03174nam a2200445 a 4500'); + my @fields = ( + MARC::Field->new( + 100, '1', ' ', + a => 'Knuth, Donald Ervin', + d => '1938', + ), + MARC::Field->new( + 245, '1', '4', + a => 'The art of computer programming', + c => 'Donald E. Knuth.', + ), + MARC::Field->new( + 650, ' ', '0', + 9 => '462', + ), + MARC::Field->new( + 952, ' ', ' ', + p => '3010023917_updated', + y => 'BK', + c => 'GEN', + e => '2001-06-25', + ), + MARC::Field->new( + 246, '', ' ', + a => 'The art of computer programming', + ), + ); + $record->append_fields(@fields); + return $record; +} + + +# C4::Context->userenv +sub Mock_userenv { + return { branchcode => 'CPL' }; +} diff --git a/tools/marc_modification_templates.pl b/tools/marc_modification_templates.pl index dde2476726..e815f604ec 100755 --- a/tools/marc_modification_templates.pl +++ b/tools/marc_modification_templates.pl @@ -1,23 +1,22 @@ #!/usr/bin/perl -# Copyright 2010 Kyle M Hall -# # 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. +# Copyright 2010 Kyle M Hall +# +# 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. +# 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. +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . -use strict; -use warnings; +use Modern::Perl; use CGI; @@ -28,7 +27,7 @@ use C4::MarcModificationTemplates; my $cgi = new CGI; -my $op = $cgi->param('op'); +my $op = $cgi->param('op') || q{}; my $template_id = $cgi->param('template_id'); my ($template, $loggedinuser, $cookie) @@ -60,7 +59,9 @@ if ( $op eq "create_template" ) { my $field_value = $cgi->param('field_value'); my $to_field = $cgi->param('to_field'); my $to_subfield = $cgi->param('to_subfield'); - my $to_regex = $cgi->param('to_regex'); + my $to_regex_search = $cgi->param('to_regex_search'); + my $to_regex_replace = $cgi->param('to_regex_replace'); + my $to_regex_modifiers = $cgi->param('to_regex_modifiers'); my $conditional = $cgi->param('conditional'); my $conditional_field = $cgi->param('conditional_field'); my $conditional_subfield = $cgi->param('conditional_subfield'); @@ -79,7 +80,9 @@ if ( $op eq "create_template" ) { $field_value, $to_field, $to_subfield, - $to_regex, + $to_regex_search, + $to_regex_replace, + $to_regex_modifiers, $conditional, $conditional_field, $conditional_subfield, @@ -98,7 +101,9 @@ if ( $op eq "create_template" ) { $field_value, $to_field, $to_subfield, - $to_regex, + $to_regex_search, + $to_regex_replace, + $to_regex_modifiers, $conditional, $conditional_field, $conditional_subfield, -- 2.39.5