use C4::Items;
use C4::Charset;
use C4::AuthoritiesMarc;
+use Koha::MarcModificationTemplates;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
=head2 BatchStageMarcRecords
($batch_id, $num_records, $num_items, @invalid_records) =
- BatchStageMarcRecords($record_type, $encoding, $marc_records, $file_name,
+ BatchStageMarcRecords($encoding, $marc_records, $file_name, $marc_modification_template,
$comments, $branch_code, $parse_items,
$leave_as_staging,
$progress_interval, $progress_callback);
my $encoding = shift;
my $marc_records = shift;
my $file_name = shift;
+ my $marc_modification_template = shift;
my $comments = shift;
my $branch_code = shift;
my $parse_items = shift;
$encoding = $charset_guessed unless $encoding;
+ ModifyRecordWithTemplate( $marc_modification_template, $marc_record ) if ( $marc_modification_template );
+
my $import_record_id;
if (scalar($marc_record->fields()) == 0) {
push @invalid_records, $marc_blob;
return;
}
+=head2
+
+ Log( $message );
+
+ Writes data to /tmp/koha.log.
+
+ This is useful for debugging forked processes
+ that do not write to the apache error log
+
+=cut
+
+sub Log {
+ my ($data) = @_;
+ open (MYFILE, '>>/tmp/koha.log');
+ print MYFILE "$data\n";
+ close (MYFILE);
+}
1;
__END__
--- /dev/null
+package Koha::MarcModificationTemplates;
+
+# Copyright 2010 Kyle M Hall <kyle.m.hall@gmail.com>
+#
+# 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.
+
+## 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 DateTime;
+
+use C4::Context;
+use Koha::SimpleMARC;
+
+use vars qw($VERSION @ISA @EXPORT);
+
+use constant DEBUG => 0;
+
+BEGIN {
+ $VERSION = 1.00; # set the version for version checking
+ @ISA = qw(Exporter);
+ @EXPORT = qw(
+ &GetModificationTemplates
+ &AddModificationTemplate
+ &DelModificationTemplate
+
+ &GetModificationTemplateAction
+ &GetModificationTemplateActions
+
+ &AddModificationTemplateAction
+ &ModModificationTemplateAction
+ &DelModificationTemplateAction
+ &MoveModificationTemplateAction
+
+ &ModifyRecordsWithTemplate
+ &ModifyRecordWithTemplate
+ );
+}
+
+
+=head1 NAME
+
+Koha::MarcModificationTemplates - Module to manage MARC Modification Templates
+
+=head1 DESCRIPTION
+
+MARC Modification Templates are a tool for marc batch imports,
+so that librarians can set up templates for various vendors'
+files telling Koha what fields to insert data into.
+
+=head1 FUNCTIONS
+
+=cut
+
+=head2 GetModificationTemplates
+
+ my @templates = GetModificationTemplates( [ $template_id ] );
+
+ Passing a $template_id will mark the given id as the selected template.
+=cut
+
+sub GetModificationTemplates {
+ my ( $template_id ) = @_;
+ C4::Koha::Log("Koha::MarcModificationTemplates::GetModificationTemplates( $template_id )") if DEBUG;
+ warn("Koha::MarcModificationTemplates::GetModificationTemplates( $template_id )") if DEBUG;
+
+ my $dbh = C4::Context->dbh;
+ my $sth = $dbh->prepare("SELECT * FROM marc_modification_templates");
+ $sth->execute();
+
+ my @templates;
+ while ( my $template = $sth->fetchrow_hashref() ) {
+ $template->{'selected'} = 1 if ( $template->{'template_id'} eq $template_id );
+ push( @templates, $template );
+ }
+
+ return @templates;
+}
+
+=head2
+ AddModificationTemplate
+
+ $template_id = AddModificationTemplate( $template_name[, $template_id ] );
+
+ If $template_id is supplied, the actions from that template will be copied
+ into the newly created template.
+=cut
+
+sub AddModificationTemplate {
+ my ( $template_name, $template_id_copy ) = @_;
+
+ my $dbh = C4::Context->dbh;
+ my $sth = $dbh->prepare("INSERT INTO marc_modification_templates ( name ) VALUES ( ? )");
+ $sth->execute( $template_name );
+
+ $sth = $dbh->prepare("SELECT * FROM marc_modification_templates WHERE name = ?");
+ $sth->execute( $template_name );
+ my $row = $sth->fetchrow_hashref();
+ my $template_id = $row->{'template_id'};
+
+ if ( $template_id_copy ) {
+ my @actions = GetModificationTemplateActions( $template_id_copy );
+ foreach my $action ( @actions ) {
+ AddModificationTemplateAction(
+ $template_id,
+ $action->{'action'},
+ $action->{'field_number'},
+ $action->{'from_field'},
+ $action->{'from_subfield'},
+ $action->{'field_value'},
+ $action->{'to_field'},
+ $action->{'to_subfield'},
+ $action->{'to_regex'},
+ $action->{'conditional'},
+ $action->{'conditional_field'},
+ $action->{'conditional_subfield'},
+ $action->{'conditional_comparison'},
+ $action->{'conditional_value'},
+ $action->{'conditional_regex'},
+ $action->{'description'},
+ );
+
+ }
+ }
+
+ return $template_id;
+}
+
+=head2
+ DelModificationTemplate
+
+ DelModificationTemplate( $template_id );
+=cut
+
+sub DelModificationTemplate {
+ my ( $template_id ) = @_;
+
+ 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
+ GetModificationTemplateAction
+
+ my $action = GetModificationTemplateAction( $mmta_id );
+=cut
+
+sub GetModificationTemplateAction {
+ my ( $mmta_id ) = @_;
+
+ my $dbh = C4::Context->dbh;
+ my $sth = $dbh->prepare("SELECT * FROM marc_modification_template_actions WHERE mmta_id = ?");
+ $sth->execute( $mmta_id );
+ my $action = $sth->fetchrow_hashref();
+
+ return $action;
+}
+
+=head2
+ GetModificationTemplateActions
+
+ my @actions = GetModificationTemplateActions( $template_id );
+=cut
+
+sub GetModificationTemplateActions {
+ my ( $template_id ) = @_;
+
+ C4::Koha::Log( "Koha::MarcModificationTemplates::GetModificationTemplateActions( $template_id )" ) if DEBUG;
+ warn( "Koha::MarcModificationTemplates::GetModificationTemplateActions( $template_id )" ) if DEBUG;
+
+ my $dbh = C4::Context->dbh;
+ my $sth = $dbh->prepare("SELECT * FROM marc_modification_template_actions WHERE template_id = ? ORDER BY ordering");
+ $sth->execute( $template_id );
+
+ my @actions;
+ while ( my $action = $sth->fetchrow_hashref() ) {
+ push( @actions, $action );
+ }
+
+ C4::Koha::Log( Data::Dumper::Dumper( @actions ) ) if DEBUG > 4;
+ warn( Data::Dumper::Dumper( @actions ) ) if DEBUG > 4;
+
+ return @actions;
+}
+
+=head2
+ AddModificationTemplateAction
+
+ 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, $conditional_value,
+ $conditional_regex, $description
+ );
+
+ Adds a new action to the given modification template.
+
+=cut
+
+sub AddModificationTemplateAction {
+ my (
+ $template_id,
+ $action,
+ $field_number,
+ $from_field,
+ $from_subfield,
+ $field_value,
+ $to_field,
+ $to_subfield,
+ $to_regex,
+ $conditional,
+ $conditional_field,
+ $conditional_subfield,
+ $conditional_comparison,
+ $conditional_value,
+ $conditional_regex,
+ $description
+ ) = @_;
+
+ C4::Koha::Log( "Koha::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,
+ $conditional_value, $conditional_regex, $description )" ) if DEBUG;
+ warn( "Koha::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,
+ $conditional_value, $conditional_regex, $description )" ) if DEBUG;
+
+ $conditional_regex ||= '0';
+
+ my $dbh = C4::Context->dbh;
+ my $sth = $dbh->prepare( 'SELECT MAX(ordering) + 1 AS next_ordering FROM marc_modification_template_actions WHERE template_id = ?' );
+ $sth->execute( $template_id );
+ my $row = $sth->fetchrow_hashref;
+ my $ordering = $row->{'next_ordering'} || 1;
+
+ my $query = "
+ INSERT INTO marc_modification_template_actions (
+ mmta_id,
+ template_id,
+ ordering,
+ action,
+ field_number,
+ from_field,
+ from_subfield,
+ field_value,
+ to_field,
+ to_subfield,
+ to_regex,
+ conditional,
+ conditional_field,
+ conditional_subfield,
+ conditional_comparison,
+ conditional_value,
+ conditional_regex,
+ description
+ )
+ VALUES ( NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )";
+
+ $sth = $dbh->prepare( $query );
+
+ $sth->execute(
+ $template_id,
+ $ordering,
+ $action,
+ $field_number,
+ $from_field,
+ $from_subfield,
+ $field_value,
+ $to_field,
+ $to_subfield,
+ $to_regex,
+ $conditional,
+ $conditional_field,
+ $conditional_subfield,
+ $conditional_comparison,
+ $conditional_value,
+ $conditional_regex,
+ $description
+ );
+}
+
+=head2
+ ModModificationTemplateAction
+
+ ModModificationTemplateAction(
+ $mmta_id, $action, $field_number, $from_field,
+ $from_subfield, $field_value, $to_field,
+ $to_subfield, $to_regex, $conditional,
+ $conditional_field, $conditional_subfield,
+ $conditional_comparison, $conditional_value,
+ $conditional_regex, $description
+ );
+
+ Modifies an existing action.
+
+=cut
+
+sub ModModificationTemplateAction {
+ my (
+ $mmta_id,
+ $action,
+ $field_number,
+ $from_field,
+ $from_subfield,
+ $field_value,
+ $to_field,
+ $to_subfield,
+ $to_regex,
+ $conditional,
+ $conditional_field,
+ $conditional_subfield,
+ $conditional_comparison,
+ $conditional_value,
+ $conditional_regex,
+ $description
+ ) = @_;
+
+ my $dbh = C4::Context->dbh;
+
+ my $query = "
+ UPDATE marc_modification_template_actions SET
+ action = ?,
+ field_number = ?,
+ from_field = ?,
+ from_subfield = ?,
+ field_value = ?,
+ to_field = ?,
+ to_subfield = ?,
+ to_regex = ?,
+ conditional = ?,
+ conditional_field = ?,
+ conditional_subfield = ?,
+ conditional_comparison = ?,
+ conditional_value = ?,
+ conditional_regex = ?,
+ description = ?
+ WHERE mmta_id = ?";
+
+ my $sth = $dbh->prepare( $query );
+
+ $sth->execute(
+ $action,
+ $field_number,
+ $from_field,
+ $from_subfield,
+ $field_value,
+ $to_field,
+ $to_subfield,
+ $to_regex,
+ $conditional,
+ $conditional_field,
+ $conditional_subfield,
+ $conditional_comparison,
+ $conditional_value,
+ $conditional_regex,
+ $description,
+ $mmta_id
+ );
+}
+
+
+=head2
+ DelModificationTemplateAction
+
+ DelModificationTemplateAction( $mmta_id );
+
+ Deletes the given template action.
+=cut
+
+sub DelModificationTemplateAction {
+ my ( $mmta_id ) = @_;
+
+ my $action = GetModificationTemplateAction( $mmta_id );
+
+ my $dbh = C4::Context->dbh;
+ my $sth = $dbh->prepare("DELETE FROM marc_modification_template_actions WHERE mmta_id = ?");
+ $sth->execute( $mmta_id );
+
+ $sth = $dbh->prepare("UPDATE marc_modification_template_actions SET ordering = ordering - 1 WHERE template_id = ? AND ordering > ?");
+ $sth->execute( $action->{'template_id'}, $action->{'ordering'} );
+}
+
+=head2
+ MoveModificationTemplateAction
+
+ MoveModificationTemplateAction( $mmta_id, $where );
+
+ Changes the order for the given action.
+ Options for $where are 'up', 'down', 'top' and 'bottom'
+=cut
+sub MoveModificationTemplateAction {
+ my ( $mmta_id, $where ) = @_;
+
+ my $action = GetModificationTemplateAction( $mmta_id );
+
+ return if ( $action->{'ordering'} eq '1' && ( $where eq 'up' || $where eq 'top' ) );
+ return if ( $action->{'ordering'} eq GetModificationTemplateActions( $action->{'template_id'} ) && ( $where eq 'down' || $where eq 'bottom' ) );
+
+ my $dbh = C4::Context->dbh;
+ my ( $sth, $query );
+
+ if ( $where eq 'up' || $where eq 'down' ) {
+
+ ## For up and down, we just swap the ordering number with the one above or below it.
+
+ ## Change the ordering for the other action
+ $query = "UPDATE marc_modification_template_actions SET ordering = ? WHERE template_id = ? AND ordering = ?";
+
+ my $ordering = $action->{'ordering'};
+ $ordering-- if ( $where eq 'up' );
+ $ordering++ if ( $where eq 'down' );
+
+ $sth = $dbh->prepare( $query );
+ $sth->execute( $action->{'ordering'}, $action->{'template_id'}, $ordering );
+
+ ## Change the ordering for this action
+ $query = "UPDATE marc_modification_template_actions SET ordering = ? WHERE mmta_id = ?";
+ $sth = $dbh->prepare( $query );
+ $sth->execute( $ordering, $action->{'mmta_id'} );
+
+ } elsif ( $where eq 'top' ) {
+
+ $sth = $dbh->prepare('UPDATE marc_modification_template_actions SET ordering = ordering + 1 WHERE template_id = ? AND ordering < ?');
+ $sth->execute( $action->{'template_id'}, $action->{'ordering'} );
+
+ $sth = $dbh->prepare('UPDATE marc_modification_template_actions SET ordering = 1 WHERE mmta_id = ?');
+ $sth->execute( $mmta_id );
+
+ } elsif ( $where eq 'bottom' ) {
+
+ my $ordering = GetModificationTemplateActions( $action->{'template_id'} );
+
+ $sth = $dbh->prepare('UPDATE marc_modification_template_actions SET ordering = ordering - 1 WHERE template_id = ? AND ordering > ?');
+ $sth->execute( $action->{'template_id'}, $action->{'ordering'} );
+
+ $sth = $dbh->prepare('UPDATE marc_modification_template_actions SET ordering = ? WHERE mmta_id = ?');
+ $sth->execute( $ordering, $mmta_id );
+
+ }
+
+}
+
+=head2
+ ModifyRecordsWithTemplate
+
+ ModifyRecordsWithTemplate( $template_id, $batch );
+
+ Accepts a template id and a MARC::Batch object.
+=cut
+
+sub ModifyRecordsWithTemplate {
+ my ( $template_id, $batch ) = @_;
+ C4::Koha::Log( "Koha::MarcModificationTemplates::ModifyRecordsWithTemplate( $template_id, $batch )" ) if DEBUG;
+ warn( "Koha::MarcModificationTemplates::ModifyRecordsWithTemplate( $template_id, $batch )" ) if DEBUG;
+
+ while ( my $record = $batch->next() ) {
+ ModifyRecordWithTemplate( $template_id, $record );
+ }
+}
+
+=head2
+ ModifyRecordWithTemplate
+
+ ModifyRecordWithTemplate( $template_id, $record )
+
+ Accepts a MARC::Record object ( $record ) and modifies
+ it based on the actions for the given $template_id
+=cut
+
+sub ModifyRecordWithTemplate {
+ my ( $template_id, $record ) = @_;
+ C4::Koha::Log( "Koha::MarcModificationTemplates::ModifyRecordWithTemplate( $template_id, $record )" ) if DEBUG;
+ warn( "Koha::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 .= " '$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 .= " )";
+ }
+
+ $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__
+
+=head1 AUTHOR
+
+Kyle M Hall
+
+=cut
--- /dev/null
+package Koha::SimpleMARC;
+
+# Copyright 2009 Kyle M. Hall <kyle.m.hall@gmail.com>
+
+use strict;
+use warnings;
+
+#use MARC::Record;
+
+require Exporter;
+
+our @ISA = qw(Exporter);
+our %EXPORT_TAGS = ( 'all' => [ qw(
+
+) ] );
+
+our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
+
+our @EXPORT = qw(
+ read_field
+ update_field
+ copy_field
+ move_field
+ delete_field
+ field_exists
+ field_equals
+);
+
+our $VERSION = '0.01';
+
+our $debug = 0;
+
+=head1 NAME
+
+SimpleMARC - Perl modle for making simple MARC record alterations.
+
+=head1 SYNOPSIS
+
+ use SimpleMARC;
+
+=head1 DESCRIPTION
+
+SimpleMARC is designed to make writing scripts
+to modify MARC records simple and easy.
+
+Every function in the modules requires a
+MARC::Record object as its first parameter.
+
+=head1 AUTHOR
+
+Kyle Hall <lt>kyle.m.hall@gmail.com<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2009 by Kyle Hall
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.8.7 or,
+at your option, any later version of Perl 5 you may have available.
+
+=head1 FUNCTIONS
+
+=head2
+
+ copy_field( $record, $fromFieldName, $fromSubfieldName, $toFieldName, $toSubfieldName[, $regex[, $n ] ] );
+
+ 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/'
+
+ 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.
+
+=cut
+
+sub copy_field {
+ my ( $record, $fromFieldName, $fromSubfieldName, $toFieldName, $toSubfieldName, $regex, $n ) = @_;
+ C4::Koha::Log( "C4::SimpleMARC::copy_field( '$record', '$fromFieldName', '$fromSubfieldName', '$toFieldName', '$toSubfieldName', '$regex', '$n' )" ) if $debug;
+
+ if ( ! ( $record && $fromFieldName && $toFieldName ) ) { return; }
+
+ my @values = read_field( $record, $fromFieldName, $fromSubfieldName );
+ @values = ( $values[$n-1] ) if ( $n );
+ C4::Koha::Log( "@values = read_field( $record, $fromFieldName, $fromSubfieldName )" ) if $debug >= 3;
+
+ if ( $regex ) {
+ foreach my $value ( @values ) {
+ C4::Koha::Log( "\$value =~ s$regex" ) if ( $debug >= 3 );
+ eval "\$value =~ s$regex";
+ }
+ }
+
+ update_field( $record, $toFieldName, $toSubfieldName, @values );
+
+}
+
+=head2
+
+ update_field( $record, $fieldName, $subfieldName, $value[, $value,[ $value ... ] ] );
+
+ Updates a field with the given value, creating it if neccessary.
+
+ If multiple values are supplied, they will be used to update a list of repeatable fields
+ until either the fields or the values are all used.
+
+ If a single value is supplied for a repeated field, that value will be used to update
+ each of the repeated fields.
+
+=cut
+
+sub update_field {
+ my ( $record, $fieldName, $subfieldName, @values ) = @_;
+ C4::Koha::Log( "C4::SimpleMARC::update_field( $record, $fieldName, $subfieldName, @values )" ) if $debug;
+
+ 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 ) ) {
+ foreach my $field ( @fields ) {
+ $field->update( "$subfieldName" => $values[$i++] );
+ }
+ } else {
+ ## Field does not exist, create it.
+ foreach my $value ( @values ) {
+ $field = MARC::Field->new( $fieldName, '', '', "$subfieldName" => $values[$i++] );
+ $record->append_fields( $field );
+ }
+ }
+ } else { ## No subfield
+ if ( my @fields = $record->field( $fieldName ) ) {
+ foreach my $field ( @fields ) {
+ $field->update( $values[$i++] );
+ }
+ } else {
+ ## Field does not exists, create it
+ foreach my $value ( @values ) {
+ $field = MARC::Field->new( $fieldName, $value );
+ $record->append_fields( $field );
+ }
+ }
+ }
+}
+
+=head2
+
+ my @values = read_field( $record, $fieldName[, $subfieldName, [, $n ] ] );
+
+ Returns an array of field values for the given field and subfield
+
+ If $n is given, it will return only the $nth value of the array.
+ E.g. If $n = 1, it return the 1st value, if $n = 3, it will return the 3rd value.
+
+=cut
+
+sub read_field {
+ my ( $record, $fieldName, $subfieldName, $n ) = @_;
+ C4::Koha::Log( "C4::SimpleMARC::read_field( '$record', '$fieldName', '$subfieldName', '$n' )" ) if $debug;
+
+ my @fields = $record->field( $fieldName );
+
+ return @fields unless $subfieldName;
+
+ my @subfields;
+ foreach my $field ( @fields ) {
+ my @sf = $field->subfield( $subfieldName );
+ push( @subfields, @sf );
+ }
+
+ if ( $n ) {
+ return $subfields[$n-1];
+ } else {
+ return @subfields;
+ }
+}
+
+=head2
+
+ $bool = field_exists( $record, $fieldName[, $subfieldName ]);
+
+ Returns true if the field exits, false otherwise.
+
+=cut
+
+sub field_exists {
+ my ( $record, $fieldName, $subfieldName ) = @_;
+ C4::Koha::Log( "C4::SimpleMARC::field_exists( $record, $fieldName, $subfieldName )" ) if $debug;
+
+ if ( ! $record ) { return; }
+
+ my $return = 0;
+ if ( $fieldName && $subfieldName ) {
+ $return = $record->field( $fieldName ) && $record->subfield( $fieldName, $subfieldName );
+ } elsif ( $fieldName ) {
+ $return = $record->field( $fieldName ) && 1;
+ }
+
+ C4::Koha::Log( "C4:SimpleMARC::field_exists: Returning '$return'" ) if $debug >= 2;
+ return $return;
+}
+
+=head2
+
+ $bool = field_equals( $record, $value, $fieldName[, $subfieldName[, $regex [, $n ] ] ]);
+
+ 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/'
+
+ 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.
+
+=cut
+
+sub field_equals {
+ my ( $record, $value, $fieldName, $subfieldName, $regex, $n ) = @_;
+ $n = 1 unless ( $n ); ## $n defaults to first field of a repeatable field series
+ C4::Koha::Log( "C4::SimpleMARC::field_equals( '$record', '$value', '$fieldName', '$subfieldName', '$regex', '$n')" ) if $debug;
+
+ if ( ! $record ) { return; }
+
+ my @field_values = read_field( $record, $fieldName, $subfieldName, $n );
+ 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";
+ } else {
+ return $field_value eq $value;
+ }
+}
+
+=head2
+
+ move_field( $record, $fromFieldName, $fromSubfieldName, $toFieldName, $toSubfieldName[, $regex [, $n ] ] );
+
+ Moves 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 moved into the new field.
+ Example: $regex = 's/Old Text/Replacement Text/'
+
+ If $n is passed, only the Nth field will be moved. $n = 1
+ will move the first repeatable field, $n = 3 will move the third.
+
+=cut
+
+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 );
+ delete_field( $record, $fromFieldName, $fromSubfieldName, $n );
+}
+
+=head2
+
+ delete_field( $record, $fieldName[, $subfieldName [, $n ] ] );
+
+ Deletes the given field.
+
+ If $n is passed, only the Nth field will be deleted. $n = 1
+ will delete the first repeatable field, $n = 3 will delete the third.
+
+=cut
+
+sub delete_field {
+ my ( $record, $fieldName, $subfieldName, $n ) = @_;
+ C4::Koha::Log( "C4::SimpleMARC::delete_field( '$record', '$fieldName', '$subfieldName', '$n' )" ) if $debug;
+
+ my @fields = $record->field( $fieldName );
+
+ @fields = ( $fields[$n-1] ) if ( $n );
+
+ if ( @fields && !$subfieldName ) {
+ foreach my $field ( @fields ) {
+ $record->delete_field( $field );
+ }
+ } elsif ( @fields && $subfieldName ) {
+ foreach my $field ( @fields ) {
+ $field->delete_subfield( code => $subfieldName );
+ }
+ }
+}
+
+=head2
+
+ _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, '', '', "$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__
(13, 'rotating_collections', 'Manage rotating collections'),
(13, 'upload_local_cover_images', 'Upload local cover images'),
(13, 'manage_patron_lists', 'Add, edit and delete patron lists and their contents'),
+ (13, 'marc_modification_templates', 'Manage marc modification templates'),
(15, 'check_expiration', 'Check the expiration of a serial'),
(15, 'claim_serials', 'Claim missing serials'),
(15, 'create_subscription', 'Create a new subscription'),
ADD CONSTRAINT patron_list_patrons_ibfk_1 FOREIGN KEY (patron_list_id) REFERENCES patron_lists (patron_list_id) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT patron_list_patrons_ibfk_2 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE;
+--
+-- Table structure for table 'marc_modification_templates'
+--
+
+CREATE TABLE IF NOT EXISTS marc_modification_templates (
+ template_id int(11) NOT NULL AUTO_INCREMENT,
+ name text NOT NULL,
+ PRIMARY KEY (template_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table 'marc_modification_template_actions'
+--
+
+CREATE TABLE IF NOT EXISTS marc_modification_template_actions (
+ mmta_id int(11) NOT NULL AUTO_INCREMENT,
+ template_id int(11) NOT NULL,
+ ordering int(3) NOT NULL,
+ action enum('delete_field','update_field','move_field','copy_field') NOT NULL,
+ field_number smallint(6) NOT NULL DEFAULT '0',
+ from_field varchar(3) NOT NULL,
+ from_subfield varchar(1) DEFAULT NULL,
+ field_value varchar(100) DEFAULT NULL,
+ to_field varchar(3) DEFAULT NULL,
+ to_subfield varchar(1) DEFAULT NULL,
+ to_regex text,
+ conditional enum('if','unless') DEFAULT NULL,
+ conditional_field varchar(3) DEFAULT NULL,
+ conditional_subfield varchar(1) DEFAULT NULL,
+ conditional_comparison enum('exists','not_exists','equals','not_equals') DEFAULT NULL,
+ conditional_value text,
+ conditional_regex tinyint(1) NOT NULL DEFAULT '0',
+ description text,
+ PRIMARY KEY (mmta_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
SetVersion($DBversion);
}
+$DBversion = "3.11.00.XXX";
+if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
+ $dbh->do("CREATE TABLE IF NOT EXISTS marc_modification_templates (
+ template_id int(11) NOT NULL auto_increment,
+ name text NOT NULL,
+ PRIMARY KEY (template_id)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;"
+ );
+
+ $dbh->do("
+ CREATE TABLE IF NOT EXISTS marc_modification_template_actions (
+ mmta_id int(11) NOT NULL auto_increment,
+ template_id int(11) NOT NULL,
+ ordering int(3) NOT NULL,
+ action enum('delete_field','update_field','move_field','copy_field') NOT NULL,
+ field_number smallint(6) NOT NULL default '0',
+ from_field varchar(3) NOT NULL,
+ from_subfield varchar(1) NULL,
+ field_value varchar(100) default NULL,
+ to_field varchar(3) default NULL,
+ to_subfield varchar(1) default NULL,
+ to_regex text,
+ conditional enum('if','unless') default NULL,
+ conditional_field varchar(3) default NULL,
+ conditional_subfield varchar(1) default NULL,
+ conditional_comparison enum('exists','not_exists','equals','not_equals') default NULL,
+ conditional_value text,
+ conditional_regex tinyint(1) NOT NULL default '0',
+ description text,
+ PRIMARY KEY (mmta_id)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+ ");
+
+ $dbh->do("INSERT INTO permissions (module_bit, code, description) VALUES ('13', 'marc_modification_templates', 'Manage marc modification templates')");
+
+ print "Upgrade to $DBversion done ( Added tables for MARC Modification Framework )\n";
+ SetVersion($DBversion);
+}
+
=head1 FUNCTIONS
=head2 TableExists($table)
<li><a href="/cgi-bin/koha/rotating_collections/rotatingCollections.pl">Rotating collections</a></li>
[% END %]
-->
+ [% IF ( CAN_user_tools_marc_modification_templates ) %]
+ <li><a href="/cgi-bin/koha/tools/marc_modification_templates.pl">Manage MARC modification templates</a></li>
+ [% END %]
[% IF ( CAN_user_tools_stage_marc_import ) %]
<li><a href="/cgi-bin/koha/tools/stage-marc-import.pl">Stage MARC for import</a></li>
[% END %]
<dd>Create and manage Bibliographic frameworks that define the characteristics of your MARC Records (field and subfield definitions) as well as templates for the MARC editor.</dd>
<dt><a href="/cgi-bin/koha/admin/koha2marclinks.pl">Koha to MARC mapping</a></dt>
<dd>Define the mapping between the Koha transactional database (SQL) and the MARC Bibliographic records. Note that the mapping can be defined through MARC Bibliographic Framework. This tool is just a shortcut to speed up linkage.</dd>
- <dt><a href="/cgi-bin/koha/admin/fieldmapping.pl">Keywords to MARC mapping</a></dt>
- <dd>Define the mapping between keywords and MARC fields, those keywords are used to find some datas independently of the framework.</dd>
+ <dt><a href="/cgi-bin/koha/admin/fieldmapping.pl">Keywords to MARC mapping</a></dt>
+ <dd>Define the mapping between keywords and MARC fields, those keywords are used to find some datas independently of the framework.</dd>
<dt><a href="/cgi-bin/koha/admin/checkmarc.pl">MARC Bibliographic framework test</a></dt>
<dd>Checks the MARC structure. If you change your MARC Bibliographic framework it's recommended that you run this tool to test for errors in your definition.</dd>
<dt><a href="/cgi-bin/koha/admin/authtypes.pl">Authority types</a></dt>
--- /dev/null
+[% INCLUDE 'doc-head-open.inc' %]
+<title>Koha › Tools › MARC Modification Templates</title>
+[% INCLUDE 'doc-head-close.inc' %]
+
+<script type="text/javascript">
+//<![CDATA[
+$(document).ready(function() {
+ $('#select_template').find("input:submit").hide();
+ $('#select_template').change(function() {
+ $('#select_template').submit();
+ });
+});
+//]]>
+</script>
+
+<script>
+function onActionChange(selectObj) {
+ // get the index of the selected option
+ var idx = selectObj.selectedIndex;
+
+ // get the value of the selected option
+ var action = selectObj.options[idx].value;
+
+ switch( action ) {
+ case 'delete_field':
+ show('field_number_block');
+ hide('with_value_block');
+ hide('to_field_block');
+ break;
+
+ case 'update_field':
+ hide('field_number_block');
+ show('with_value_block');
+ hide('to_field_block');
+ break;
+
+ case 'move_field':
+ show('field_number_block');
+ hide('with_value_block');
+ show('to_field_block');
+ break;
+
+ case 'copy_field':
+ show('field_number_block');
+ hide('with_value_block');
+ show('to_field_block');
+ break;
+
+ }
+}
+
+function onConditionalChange(selectObj) {
+ // get the index of the selected option
+ var idx = selectObj.selectedIndex;
+
+ // get the value of the selected option
+ var action = selectObj.options[idx].value;
+
+ switch( action ) {
+ case '':
+ hide('conditional_block');
+ break;
+
+ case 'if':
+ case 'unless':
+ show('conditional_block');
+ break;
+ }
+}
+
+function onConditionalComparisonChange(selectObj) {
+ // get the index of the selected option
+ var idx = selectObj.selectedIndex;
+
+ // get the value of the selected option
+ var action = selectObj.options[idx].value;
+
+ switch( action ) {
+ case 'equals':
+ case 'not_equals':
+ show('conditional_comparison_block');
+ break;
+
+ default:
+ hide('conditional_comparison_block');
+ break;
+ }
+}
+
+function onToFieldRegexChange( checkboxObj ) {
+ if ( checkboxObj.checked ) {
+ show('to_field_regex_value_block');
+ } else {
+ hide('to_field_regex_value_block');
+ }
+}
+
+function onConditionalRegexChange( checkboxObj ) {
+ if ( checkboxObj.checked ) {
+ document.getElementById( 'match_regex_prefix' ).style.visibility='visible';
+ } else {
+ document.getElementById( 'match_regex_prefix' ).style.visibility='hidden';
+ }
+}
+
+function show(eltId) {
+ elt = document.getElementById( eltId );
+ elt.style.display='inline';
+}
+
+function hide(eltId) {
+ clearFormElements( eltId );
+ elt = document.getElementById( eltId );
+ elt.style.display='none';
+}
+
+function clearFormElements(divId) {
+ myBlock = document.getElementById( divId );
+
+ var inputElements = myBlock.getElementsByTagName( "input" );
+ for (var i = 0; i < inputElements.length; i++) {
+ switch( inputElements[i].type ) {
+ case "text":
+ inputElements[i].value = '';
+ break;
+ case "checkbox":
+ inputElements[i].checked = false;
+ break;
+ }
+ }
+
+ var selectElements = myBlock.getElementsByTagName( "select" );
+ for (var i = 0; i < selectElements.length; i++) {
+ selectElements[i].selectedIndex = 0;
+ }
+
+}
+
+function confirmDelete() {
+ var agree = confirm("Are you sure you wish to delete this template?");
+ return agree;
+}
+
+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,
+ conditional_comparison, conditional_value, conditional_regex, description
+) {
+ document.getElementById('mmta_id').value = mmta_id;
+
+ setSelectByValue( 'action', action );
+ document.getElementById('action').onchange();
+
+ setSelectByValue( 'field_number', field_number );
+
+ document.getElementById('from_field').value = from_field;
+ document.getElementById('from_subfield').value = from_subfield;
+ 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;
+
+ document.getElementById('to_field_regex').checked = to_regex.length;
+ document.getElementById('to_field_regex').onchange();
+
+ setSelectByValue( 'conditional', conditional );
+ document.getElementById('conditional').onchange();
+
+ document.getElementById('conditional_field').value = conditional_field;
+ document.getElementById('conditional_subfield').value = conditional_subfield;
+
+ setSelectByValue( 'conditional_comparison', conditional_comparison );
+ document.getElementById('conditional_comparison').onchange();
+
+ document.getElementById('conditional_value').value = conditional_value;
+
+ document.getElementById('conditional_regex').checked = parseInt( conditional_regex );
+
+ document.getElementById('description').value = description;
+
+ window.modaction_legend_innerhtml = document.getElementById('modaction_legend').innerhtml;
+ document.getElementById('modaction_legend').innerhtml = "Edit Action " + ordering;
+
+ window.action_submit_value = document.getElementById('action_submit').value;
+ document.getElementById('action_submit').value = "Update Action";
+
+ show('cancel_edit');
+}
+
+function cancelEditAction() {
+ document.getElementById('mmta_id').value = '';
+
+ setSelectByValue( 'action', 'delete_field' );
+ document.getElementById('action').onchange();
+
+ document.getElementById('from_field').value = '';
+ document.getElementById('from_subfield').value = '';
+ document.getElementById('field_value').value = '';
+ document.getElementById('to_field').value = '';
+ document.getElementById('to_subfield').value = '';
+ document.getElementById('to_regex').value = '';
+
+ document.getElementById('to_field_regex').checked = false;
+ document.getElementById('to_field_regex').onchange();
+
+ setSelectByValue( 'conditional', '' );
+ document.getElementById('conditional').onchange();
+
+ document.getElementById('conditional_field').value = '';
+ document.getElementById('conditional_subfield').value = '';
+
+ setSelectByValue( 'conditional_comparison', '' );
+ document.getElementById('conditional_comparison').onchange();
+
+ document.getElementById('conditional_value').value = '';
+
+ document.getElementById('conditional_regex').checked = false;
+
+ document.getElementById('modaction_legend').innerhtml = window.modaction_legend_innerhtml;
+ document.getElementById('action_submit').value = window.action_submit_value;
+
+ hide('cancel_edit');
+}
+
+function setSelectByValue( selectId, value ) {
+ s = document.getElementById( selectId );
+
+ for ( i = 0; i < s.options.length; i++ ) {
+ if ( s.options[i].value == value ) {
+ s.selectedIndex = i;
+ }
+ }
+}
+
+</script>
+
+</head>
+
+<body>
+[% INCLUDE 'header.inc' %]
+[% INCLUDE 'cat-search.inc' %]
+
+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> › MARC Modification Templates</div>
+
+<div id="doc3" class="yui-t2">
+ <div id="yui-main">
+ <div class="yui-b">
+ <h2>MARC Modification Templates</h2>
+
+ [% IF ( TemplatesLoop ) %]
+
+ <form method="get" action="/cgi-bin/koha/tools/marc_modification_templates.pl" id="select_template">
+ <label for="select_template">Template: </label>
+ <select name="template_id" id="select_template" style="width:20em;">
+ [% FOREACH TemplatesLoo IN TemplatesLoop %]
+ <option value="[% TemplatesLoo.template_id %]" [% IF ( TemplatesLoo.selected ) %] selected [% END %] > [% TemplatesLoo.name %]</option>
+ [% END %]
+ </select>
+ <input type="hidden" name="op" value="select_template">
+ <input type="submit" value="Go" />
+ </form>
+
+ <form method="get" action="/cgi-bin/koha/tools/marc_modification_templates.pl" id="delete_template">
+ <input type="hidden" name="template_id" value="[% template_id %]" />
+ <input type="hidden" name="op" value="delete_template">
+ <input type="submit" value="Delete Template" onClick="return confirmDelete()" />
+ </form>
+
+
+ [% IF ( ActionsLoop ) %]
+ <table>
+ <caption>Actions for this template</caption>
+
+ <tr>
+ <th>Change Order</th>
+ <th>Order</th>
+ <th>Action</th>
+ <th>Description</th>
+ <th> </th>
+ <th> </th>
+ </tr>
+
+ [% FOREACH ActionsLoo IN ActionsLoop %]
+ <tr>
+ <td style="white-space:nowrap;">
+ <a title="Move Action Up" href="marc_modification_templates.pl?op=move_action&where=up&template_id=[% ActionsLoo.template_id %]&mmta_id=[% ActionsLoo.mmta_id %]">
+ <img src="/intranet-tmpl/[% theme %]/img/go-up.png" border="0" alt="Go up" />
+ </a>
+
+ <a title="Move Action To Top" href="marc_modification_templates.pl?op=move_action&where=top&template_id=[% ActionsLoo.template_id %]&mmta_id=[% ActionsLoo.mmta_id %]">
+ <img src="/intranet-tmpl/[% theme %]/img/go-top.png" border="0" alt="Go top" />
+ </a>
+
+ <a title="Move Action To Bottom" href="marc_modification_templates.pl?op=move_action&where=bottom&template_id=[% ActionsLoo.template_id %]&mmta_id=[% ActionsLoo.mmta_id %]">
+ <img src="/intranet-tmpl/[% theme %]/img/go-bottom.png" border="0" alt="Go bottom" />
+ </a>
+
+ <a title="Move Action Down" href="marc_modification_templates.pl?op=move_action&where=down&template_id=[% ActionsLoo.template_id %]&mmta_id=[% ActionsLoo.mmta_id %]">
+ <img src="/intranet-tmpl/[% theme %]/img/go-down.png" border="0" alt="Go down" />
+ </a>
+ </td>
+
+ <td>[% ActionsLoo.ordering %]</td>
+ <td>
+ [% IF ( ActionsLoo.action_delete_field ) %] Delete [% END %]
+ [% IF ( ActionsLoo.action_update_field ) %] Update [% END %]
+ [% IF ( ActionsLoo.action_move_field ) %] Move [% END %]
+ [% IF ( ActionsLoo.action_copy_field ) %] Copy [% END %]
+
+ [% UNLESS ( ActionsLoo.action_update_field ) %]
+ [% IF ( ActionsLoo.field_number ) %]
+ 1st
+ [% END %]
+ [% END %]
+
+ field
+
+ [% ActionsLoo.from_field %][% IF ( ActionsLoo.from_subfield ) %]$[% ActionsLoo.from_subfield %][% END %]
+
+ [% IF ( ActionsLoo.field_value ) %]
+ with value <i>[% ActionsLoo.field_value %]</i>
+ [% END %]
+
+ [% IF ( ActionsLoo.to_field ) %]
+ to [% ActionsLoo.to_field %][% IF ( ActionsLoo.to_subfield ) %]$[% ActionsLoo.to_subfield %][% END %]
+
+ [% IF ( ActionsLoo.to_regex ) %]
+ using RegEx s<strong>[% ActionsLoo.to_regex %]</strong>
+ [% END %]
+ [% END %]
+
+ [% IF ( ActionsLoo.conditional ) %]
+ [% IF ( ActionsLoo.conditional_if ) %] if [% END %]
+ [% IF ( ActionsLoo.conditional_unless ) %] unless [% END %]
+
+ [% ActionsLoo.conditional_field %][% IF ( ActionsLoo.conditional_subfield ) %]$[% ActionsLoo.conditional_subfield %][% END %]
+
+ [% IF ( ActionsLoo.conditional_comparison_exists ) %] exists [% END %]
+ [% IF ( ActionsLoo.conditional_comparison_not_exists ) %] does not exist [% END %]
+ [% IF ( ActionsLoo.conditional_comparison_equals ) %] matches [% END %]
+ [% IF ( ActionsLoo.conditional_comparison_not_equals ) %] does not match [% END %]
+
+ [% IF ( ActionsLoo.conditional_regex ) %] RegEx m[% END %]<strong>[% ActionsLoo.conditional_value %]</strong>
+ [% END %]
+ </td>
+ <td>[% ActionsLoo.description %]</td>
+ <td><a href="#modaction" onclick='editAction(
+ "[% ActionsLoo.mmta_id |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]",
+ "[% ActionsLoo.ordering |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]",
+ "[% ActionsLoo.action |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]",
+ "[% ActionsLoo.field_number |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]",
+ "[% ActionsLoo.from_field |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]",
+ "[% ActionsLoo.from_subfield |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]",
+ "[% ActionsLoo.field_value |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]",
+ "[% ActionsLoo.to_field |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]",
+ "[% ActionsLoo.to_subfield |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]",
+ "[% ActionsLoo.to_regex |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]",
+ "[% ActionsLoo.conditional |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]",
+ "[% ActionsLoo.conditional_field |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]",
+ "[% ActionsLoo.conditional_subfield |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]",
+ "[% ActionsLoo.conditional_comparison |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]",
+ "[% ActionsLoo.conditional_value |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]",
+ "[% ActionsLoo.conditional_regex |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]",
+ "[% ActionsLoo.description |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') %]"
+ )'>Edit</a></td>
+ <td><a href="marc_modification_templates.pl?template_id=[% ActionsLoo.template_id %]&op=delete_action&mmta_id=[% ActionsLoo.mmta_id %]">Delete</a></td>
+ </tr>
+ [% END %]
+ </table>
+ [% ELSE %]
+ <div class="dialog message"><p>There are no defined actions for this template.</p></div>
+ [% END %]
+
+ <form method="post" action="/cgi-bin/koha/tools/marc_modification_templates.pl" id="add_action" >
+ <a name="modaction"></a>
+ <fieldset>
+ <legend id="modaction_legend">Add A New Action</legend>
+
+ <select name="action" id="action" onchange="onActionChange(this);">
+ <option value="delete_field">Delete</option>
+ <option value="update_field">Add/Update</option>
+ <option value="move_field">Move</option>
+ <option value="copy_field">Copy</option>
+ </select>
+
+ <span id="field_number_block">
+ <select name="field_number" id="field_number">
+ <option value="0">All</option>
+ <option value="1">1st</option>
+ </select>
+ </span>
+
+ field(s) <input type="text" name="from_field" id="from_field" size="3" maxlength="3" /> <input type="text" name="from_subfield" id="from_subfield" size="1" maxlength="1" />
+
+ <span name="with_value_block" id="with_value_block" style="display:none;">
+ with value <input type="text" name="field_value" id="field_value" />
+ </span>
+
+ <span name="to_field_block" id="to_field_block" style="display:none;">
+ to field <input type="text" name="to_field" id="to_field" size="3" maxlength="3" /> <input type="text" name="to_subfield" id="to_subfield" size="1" maxlength="1" />
+
+ <span name="to_field_regex_block" id="to_field_regex_block">
+ <sup>
+ <label for="to_field_regex">RegEx</label>
+ <input type="checkbox" name="to_field_regex" id="to_field_regex" onchange="onToFieldRegexChange(this);" />
+
+ <span name="to_field_regex_value_block" id="to_field_regex_value_block" style="display:none;">
+ s<input type="text" name="to_regex" id="to_regex" />
+ </span>
+ </sup>
+ </span>
+ </span>
+
+ <p/>
+
+ <select name="conditional" id="conditional" onchange="onConditionalChange(this);">
+ <option value="" selected />
+ <option value="if">if</option>
+ <option value="unless">unless</option>
+ </select>
+
+ <span name="conditional_block" id="conditional_block" style="display:none;">
+ field <input type="text" name="conditional_field" id="conditional_field" size="3" maxlength="3" /> <input type="text" name="conditional_subfield" id="conditional_subfield" size="1" maxlength="1" />
+
+ <select name="conditional_comparison" id="conditional_comparison" onchange="onConditionalComparisonChange(this);">
+ <option value="" />
+ <option value="exists">exists</option>
+ <option value="not_exists">doesn't exist</option>
+ <option value="equals">matches</option>
+ <option value="not_equals">doesn't match</option>
+ </select>
+
+ <span name="conditional_comparison_block" id="conditional_comparison_block" style="display:none;">
+
+ <span id="match_regex_prefix" style="visibility:hidden;">m</span><input type="text" id="conditional_value" name="conditional_value" />
+
+ <sup>
+ <label for="conditional_regex">RegEx</label>
+ <input type="checkbox" name="conditional_regex" id="conditional_regex" onchange="onConditionalRegexChange(this);" />
+ </sup>
+
+ </span>
+ </span>
+
+ <input type="hidden" name="template_id" value="[% template_id %]" />
+ <input type="hidden" name="mmta_id" id="mmta_id" />
+ <input type="hidden" name="op" value="add_action" />
+
+ <br/><br/>
+ <label for="description">Description:</label>
+ <input type="text" name="description" id="description" size="60" />
+
+ <br/><br/>
+ <input id="action_submit" type="submit" value="Add Action" /> <a href="#modaction" id="cancel_edit" onclick="cancelEditAction();" style="display:none;">Cancel</a>
+
+ </fieldset>
+ </form>
+
+ [% ELSE %]
+ <div class="dialog message"><p>There are no defined templates. Please create a template first.</p></div>
+ [% END %]
+
+ <form method="post" action="/cgi-bin/koha/tools/marc_modification_templates.pl" id="add_template" >
+ <fieldset>
+ <legend>Create A New Template</legend>
+
+ <label for="template_name">Name: </label>
+ <input name="template_name" id="template_name" type="text" size="30" />
+
+ <input type="hidden" name="op" value="create_template" />
+ <input type="submit" value="Create Template" />
+
+ [% IF ( template_id ) %]
+ <input type="hidden" name="template_id" value="[% template_id %]" />
+ <input type="checkbox" name="duplicate_current_template" id="duplicate_current_template" />
+ <label for="duplicate_current_template">Duplicate Current Template</label>
+ [% END %]
+ </fieldset>
+ </form>
+
+
+
+ </div>
+ </div>
+
+ <div class="yui-b">
+ [% INCLUDE 'tools-menu.inc' %]
+ </div>
+</div>
+[% INCLUDE 'intranet-bottom.inc' %]
<select name="encoding" id="encoding"><option value="utf8" selected="selected">UTF-8 (Default)</option><option value="MARC-8">MARC 8</option><option value="ISO_5426">ISO 5426</option><option value="ISO_6937">ISO 6937</option><option value=ISO_8859-1">ISO 8859-1</option><option value="EUC-KR">EUC-KR</option></select>
</li>
</ol></fieldset>
+ [% IF MarcModificationTemplatesLoop %]
+ <fieldset class="rows">
+ <legend>Use MARC Modification Template:</legend>
+ <ol>
+ <li>
+ <label for="comments">Modify record using the following template: </label>
+ <select name="marc_modification_template_id" id="marc_modification_template_id">
+ <option value="">Do not use.</option>
+ [% FOREACH mmt IN MarcModificationTemplatesLoop %]
+ <option value="[% mmt.template_id %]">[% mmt.name %]</option>
+ [% END %]
+ </select>
+ </li>
+ </ol>
+ </fieldset>
+ [% END %]
+
<fieldset class="rows">
<legend>Look for existing records in catalog?</legend>
<ol><li><label for="matcher">Record matching rule:</label>
<!--
[% IF ( CAN_user_tools_rotating_collections ) %]
<dt><a href="/cgi-bin/koha/rotating_collections/rotatingCollections.pl">Rotating collections</a></dt>
- <dd>Manage Rotating Collections</dd>
+ <dd>Manage Rotating Collections</dd>
[% END %]
-->
+ [% IF ( CAN_user_tools_marc_modification_templates ) %]
+ <dt><a href="/cgi-bin/koha/tools/marc_modification_templates.pl">MARC Modification Templates</a></dt>
+ <dd>Manage templates for modifying MARC records during import.</dd>
+ [% END %]
+
[% IF ( CAN_user_tools_stage_marc_import ) %]
<dt><a href="/cgi-bin/koha/tools/stage-marc-import.pl">Stage MARC records for import</a></dt>
<dd>Stage MARC records into the reservoir.</dd>
--- /dev/null
+#!/usr/bin/perl
+# Copyright 2010 Kyle M Hall <kyle.m.hall@gmail.com>
+#
+# 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 strict;
+use warnings;
+
+use CGI;
+
+use C4::Auth;
+use C4::Koha;
+use C4::Output;
+use Koha::MarcModificationTemplates;
+
+my $cgi = new CGI;
+
+my $op = $cgi->param('op');
+my $template_id = $cgi->param('template_id');
+
+my ($template, $loggedinuser, $cookie)
+ = get_template_and_user({template_name => "tools/marc_modification_templates.tmpl",
+ query => $cgi,
+ type => "intranet",
+ authnotrequired => 0,
+ flagsrequired => { tools => 'marc_modfication_templates' },
+ debug => 1,
+ });
+
+if ( $op eq "create_template" ) {
+ $template_id = '' unless $cgi->param('duplicate_current_template');
+ $template_id = AddModificationTemplate( $cgi->param('template_name'), $template_id );
+
+} elsif ( $op eq "delete_template" ) {
+
+ DelModificationTemplate( $template_id );
+ $template_id = '';
+
+} elsif ( $op eq "add_action" ) {
+
+ my $mmta_id = $cgi->param('mmta_id');
+ my $action = $cgi->param('action');
+ my $field_number = $cgi->param('field_number');
+ my $from_field = $cgi->param('from_field');
+ my $from_subfield = $cgi->param('from_subfield');
+ 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 $conditional = $cgi->param('conditional');
+ my $conditional_field = $cgi->param('conditional_field');
+ my $conditional_subfield = $cgi->param('conditional_subfield');
+ my $conditional_comparison = $cgi->param('conditional_comparison');
+ my $conditional_value = $cgi->param('conditional_value');
+ my $conditional_regex = $cgi->param('conditional_regex') eq 'on';
+ my $description = $cgi->param('description');
+
+ unless ( $mmta_id ) {
+ 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,
+ $conditional_value,
+ $conditional_regex,
+ $description
+ );
+ } else {
+ ModModificationTemplateAction(
+ $mmta_id,
+ $action,
+ $field_number,
+ $from_field,
+ $from_subfield,
+ $field_value,
+ $to_field,
+ $to_subfield,
+ $to_regex,
+ $conditional,
+ $conditional_field,
+ $conditional_subfield,
+ $conditional_comparison,
+ $conditional_value,
+ $conditional_regex,
+ $description
+ );
+
+ }
+
+} elsif ( $op eq "delete_action" ) {
+ DelModificationTemplateAction( $cgi->param('mmta_id') );
+
+} elsif ( $op eq "move_action" ) {
+
+ MoveModificationTemplateAction( $cgi->param('mmta_id'), $cgi->param('where') );
+
+}
+
+my @templates = GetModificationTemplates( $template_id );
+
+unless ( $template_id ) {
+ $template_id = $templates[0]->{'template_id'};
+ @templates = GetModificationTemplates( $template_id );
+}
+
+my @actions = GetModificationTemplateActions( $template_id );
+foreach my $action ( @actions ) {
+ $action->{'action_delete_field'} = ( $action->{'action'} eq 'delete_field' );
+ $action->{'action_update_field'} = ( $action->{'action'} eq 'update_field' );
+ $action->{'action_move_field'} = ( $action->{'action'} eq 'move_field' );
+ $action->{'action_copy_field'} = ( $action->{'action'} eq 'copy_field' );
+
+ $action->{'conditional_if'} = ( $action->{'conditional'} eq 'if' );
+ $action->{'conditional_unless'} = ( $action->{'conditional'} eq 'unless' );
+
+ $action->{'conditional_comparison_exists'} = ( $action->{'conditional_comparison'} eq 'exists' );
+ $action->{'conditional_comparison_not_exists'} = ( $action->{'conditional_comparison'} eq 'not_exists' );
+ $action->{'conditional_comparison_equals'} = ( $action->{'conditional_comparison'} eq 'equals' );
+ $action->{'conditional_comparison_not_equals'} = ( $action->{'conditional_comparison'} eq 'not_equals' );
+}
+
+$template->param(
+ TemplatesLoop => \@templates,
+ ActionsLoop => \@actions,
+
+ template_id => $template_id,
+);
+
+output_html_with_http_headers $cgi, $cookie, $template->output;
use C4::Matcher;
use C4::UploadedFile;
use C4::BackgroundJob;
+use Koha::MarcModificationTemplates;
my $input = new CGI;
my $dbh = C4::Context->dbh;
my $comments = $input->param('comments');
my $record_type = $input->param('record_type');
my $encoding = $input->param('encoding');
+my $marc_modification_template = $input->param('marc_modification_template_id');
+
my ($template, $loggedinuser, $cookie)
= get_template_and_user({template_name => "tools/stage-marc-import.tmpl",
query => $input,
}
# FIXME branch code
- my ($batch_id, $num_valid, $num_items, @import_errors) = BatchStageMarcRecords($record_type, $encoding, $marcrecord, $filename, $comments, '', $parse_items, 0, 50, staging_progress_callback($job, $dbh));
+ my ($batch_id, $num_valid, $num_items, @import_errors) = BatchStageMarcRecords($record_type, $encoding, $marcrecord, $filename, $marc_modification_template, $comments, '', $parse_items, 0, 50, staging_progress_callback($job, $dbh));
$dbh->commit();
matcher_code => $matcher_code,
import_batch_id => $batch_id
);
+
+
}
} else {
}
my @matchers = C4::Matcher::GetMatcherList();
$template->param(available_matchers => \@matchers);
+
+ my @templates = GetModificationTemplates();
+ $template->param( MarcModificationTemplatesLoop => \@templates );
+
}
output_html_with_http_headers $input, $cookie, $template->output;