1 package C4::MarcModificationTemplates;
3 # This file is part of Koha.
5 # Copyright 2010 Kyle M Hall <kyle.m.hall@gmail.com>
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
21 ## Parts of this module are used from cgi scripts that are detached from apache before
22 ## execution. For this reason, the C4::Koha::Log function has been used to capture
23 ## output for debugging purposes.
32 use vars qw($VERSION @ISA @EXPORT);
34 use constant DEBUG => 0;
37 $VERSION = 1.00; # set the version for version checking
40 &GetModificationTemplates
41 &AddModificationTemplate
42 &DelModificationTemplate
44 &GetModificationTemplateAction
45 &GetModificationTemplateActions
47 &AddModificationTemplateAction
48 &ModModificationTemplateAction
49 &DelModificationTemplateAction
50 &MoveModificationTemplateAction
52 &ModifyRecordsWithTemplate
53 &ModifyRecordWithTemplate
60 C4::MarcModificationTemplates - Module to manage MARC Modification Templates
64 MARC Modification Templates are a tool for marc batch imports,
65 so that librarians can set up templates for various vendors'
66 files telling Koha what fields to insert data into.
72 =head2 GetModificationTemplates
74 my @templates = GetModificationTemplates( [ $template_id ] );
76 Passing a $template_id will mark the given id as the selected template.
79 sub GetModificationTemplates {
80 my ( $template_id ) = @_;
81 C4::Koha::Log("C4::MarcModificationTemplates::GetModificationTemplates( $template_id )") if DEBUG;
82 warn("C4::MarcModificationTemplates::GetModificationTemplates( $template_id )") if DEBUG;
84 my $dbh = C4::Context->dbh;
85 my $sth = $dbh->prepare("SELECT * FROM marc_modification_templates");
89 while ( my $template = $sth->fetchrow_hashref() ) {
90 $template->{'selected'} = 1 if ( $template->{'template_id'} eq $template_id );
91 push( @templates, $template );
98 AddModificationTemplate
100 $template_id = AddModificationTemplate( $template_name[, $template_id ] );
102 If $template_id is supplied, the actions from that template will be copied
103 into the newly created template.
106 sub AddModificationTemplate {
107 my ( $template_name, $template_id_copy ) = @_;
109 my $dbh = C4::Context->dbh;
110 my $sth = $dbh->prepare("INSERT INTO marc_modification_templates ( name ) VALUES ( ? )");
111 $sth->execute( $template_name );
113 $sth = $dbh->prepare("SELECT * FROM marc_modification_templates WHERE name = ?");
114 $sth->execute( $template_name );
115 my $row = $sth->fetchrow_hashref();
116 my $template_id = $row->{'template_id'};
118 if ( $template_id_copy ) {
119 my @actions = GetModificationTemplateActions( $template_id_copy );
120 foreach my $action ( @actions ) {
121 AddModificationTemplateAction(
124 $action->{'field_number'},
125 $action->{'from_field'},
126 $action->{'from_subfield'},
127 $action->{'field_value'},
128 $action->{'to_field'},
129 $action->{'to_subfield'},
130 $action->{'to_regex_search'},
131 $action->{'to_regex_replace'},
132 $action->{'to_regex_modifiers'},
133 $action->{'conditional'},
134 $action->{'conditional_field'},
135 $action->{'conditional_subfield'},
136 $action->{'conditional_comparison'},
137 $action->{'conditional_value'},
138 $action->{'conditional_regex'},
139 $action->{'description'},
149 DelModificationTemplate
151 DelModificationTemplate( $template_id );
154 sub DelModificationTemplate {
155 my ( $template_id ) = @_;
157 my $dbh = C4::Context->dbh;
158 my $sth = $dbh->prepare("DELETE FROM marc_modification_templates WHERE template_id = ?");
159 $sth->execute( $template_id );
163 GetModificationTemplateAction
165 my $action = GetModificationTemplateAction( $mmta_id );
168 sub GetModificationTemplateAction {
169 my ( $mmta_id ) = @_;
171 my $dbh = C4::Context->dbh;
172 my $sth = $dbh->prepare("SELECT * FROM marc_modification_template_actions WHERE mmta_id = ?");
173 $sth->execute( $mmta_id );
174 my $action = $sth->fetchrow_hashref();
180 GetModificationTemplateActions
182 my @actions = GetModificationTemplateActions( $template_id );
185 sub GetModificationTemplateActions {
186 my ( $template_id ) = @_;
188 C4::Koha::Log( "C4::MarcModificationTemplates::GetModificationTemplateActions( $template_id )" ) if DEBUG;
189 warn( "C4::MarcModificationTemplates::GetModificationTemplateActions( $template_id )" ) if DEBUG;
191 my $dbh = C4::Context->dbh;
192 my $sth = $dbh->prepare("SELECT * FROM marc_modification_template_actions WHERE template_id = ? ORDER BY ordering");
193 $sth->execute( $template_id );
196 while ( my $action = $sth->fetchrow_hashref() ) {
197 push( @actions, $action );
200 C4::Koha::Log( Data::Dumper::Dumper( @actions ) ) if DEBUG > 4;
201 warn( Data::Dumper::Dumper( @actions ) ) if DEBUG > 4;
207 AddModificationTemplateAction
209 AddModificationTemplateAction(
210 $template_id, $action, $field_number,
211 $from_field, $from_subfield, $field_value,
212 $to_field, $to_subfield, $to_regex_search, $to_regex_replace, $to_regex_modifiers
213 $conditional, $conditional_field, $conditional_subfield,
214 $conditional_comparison, $conditional_value,
215 $conditional_regex, $description
218 Adds a new action to the given modification template.
222 sub AddModificationTemplateAction {
237 $conditional_subfield,
238 $conditional_comparison,
244 C4::Koha::Log( "C4::MarcModificationTemplates::AddModificationTemplateAction( $template_id, $action,
245 $field_number, $from_field, $from_subfield, $field_value, $to_field, $to_subfield,
246 $to_regex_search, $to_regex_replace, $to_regex_modifiers, $conditional, $conditional_field, $conditional_subfield, $conditional_comparison,
247 $conditional_value, $conditional_regex, $description )" ) if DEBUG;
248 warn( "C4::MarcModificationTemplates::AddModificationTemplateAction( $template_id, $action,
249 $field_number, $from_field, $from_subfield, $field_value, $to_field, $to_subfield,
250 $to_regex_search, $to_regex_replace, $to_regex_modifiers, $conditional, $conditional_field, $conditional_subfield, $conditional_comparison,
251 $conditional_value, $conditional_regex, $description )" ) if DEBUG;
253 $conditional_regex ||= '0';
255 my $dbh = C4::Context->dbh;
256 my $sth = $dbh->prepare( 'SELECT MAX(ordering) + 1 AS next_ordering FROM marc_modification_template_actions WHERE template_id = ?' );
257 $sth->execute( $template_id );
258 my $row = $sth->fetchrow_hashref;
259 my $ordering = $row->{'next_ordering'} || 1;
262 INSERT INTO marc_modification_template_actions (
278 conditional_subfield,
279 conditional_comparison,
284 VALUES ( NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )";
286 $sth = $dbh->prepare( $query );
303 $conditional_subfield,
304 $conditional_comparison,
312 ModModificationTemplateAction
314 ModModificationTemplateAction(
315 $mmta_id, $action, $field_number, $from_field,
316 $from_subfield, $field_value, $to_field,
317 $to_subfield, $to_regex_search, $to_regex_replace, $to_regex_modifiers, $conditional,
318 $conditional_field, $conditional_subfield,
319 $conditional_comparison, $conditional_value,
320 $conditional_regex, $description
323 Modifies an existing action.
327 sub ModModificationTemplateAction {
342 $conditional_subfield,
343 $conditional_comparison,
349 my $dbh = C4::Context->dbh;
352 UPDATE marc_modification_template_actions SET
361 to_regex_replace = ?,
362 to_regex_modifiers = ?,
364 conditional_field = ?,
365 conditional_subfield = ?,
366 conditional_comparison = ?,
367 conditional_value = ?,
368 conditional_regex = ?,
372 my $sth = $dbh->prepare( $query );
387 $conditional_subfield,
388 $conditional_comparison,
398 DelModificationTemplateAction
400 DelModificationTemplateAction( $mmta_id );
402 Deletes the given template action.
405 sub DelModificationTemplateAction {
406 my ( $mmta_id ) = @_;
408 my $action = GetModificationTemplateAction( $mmta_id );
410 my $dbh = C4::Context->dbh;
411 my $sth = $dbh->prepare("DELETE FROM marc_modification_template_actions WHERE mmta_id = ?");
412 $sth->execute( $mmta_id );
414 $sth = $dbh->prepare("UPDATE marc_modification_template_actions SET ordering = ordering - 1 WHERE template_id = ? AND ordering > ?");
415 $sth->execute( $action->{'template_id'}, $action->{'ordering'} );
419 MoveModificationTemplateAction
421 MoveModificationTemplateAction( $mmta_id, $where );
423 Changes the order for the given action.
424 Options for $where are 'up', 'down', 'top' and 'bottom'
426 sub MoveModificationTemplateAction {
427 my ( $mmta_id, $where ) = @_;
429 my $action = GetModificationTemplateAction( $mmta_id );
431 return if ( $action->{'ordering'} eq '1' && ( $where eq 'up' || $where eq 'top' ) );
432 return if ( $action->{'ordering'} eq GetModificationTemplateActions( $action->{'template_id'} ) && ( $where eq 'down' || $where eq 'bottom' ) );
434 my $dbh = C4::Context->dbh;
437 if ( $where eq 'up' || $where eq 'down' ) {
439 ## For up and down, we just swap the ordering number with the one above or below it.
441 ## Change the ordering for the other action
442 $query = "UPDATE marc_modification_template_actions SET ordering = ? WHERE template_id = ? AND ordering = ?";
444 my $ordering = $action->{'ordering'};
445 $ordering-- if ( $where eq 'up' );
446 $ordering++ if ( $where eq 'down' );
448 $sth = $dbh->prepare( $query );
449 $sth->execute( $action->{'ordering'}, $action->{'template_id'}, $ordering );
451 ## Change the ordering for this action
452 $query = "UPDATE marc_modification_template_actions SET ordering = ? WHERE mmta_id = ?";
453 $sth = $dbh->prepare( $query );
454 $sth->execute( $ordering, $action->{'mmta_id'} );
456 } elsif ( $where eq 'top' ) {
458 $sth = $dbh->prepare('UPDATE marc_modification_template_actions SET ordering = ordering + 1 WHERE template_id = ? AND ordering < ?');
459 $sth->execute( $action->{'template_id'}, $action->{'ordering'} );
461 $sth = $dbh->prepare('UPDATE marc_modification_template_actions SET ordering = 1 WHERE mmta_id = ?');
462 $sth->execute( $mmta_id );
464 } elsif ( $where eq 'bottom' ) {
466 my $ordering = GetModificationTemplateActions( $action->{'template_id'} );
468 $sth = $dbh->prepare('UPDATE marc_modification_template_actions SET ordering = ordering - 1 WHERE template_id = ? AND ordering > ?');
469 $sth->execute( $action->{'template_id'}, $action->{'ordering'} );
471 $sth = $dbh->prepare('UPDATE marc_modification_template_actions SET ordering = ? WHERE mmta_id = ?');
472 $sth->execute( $ordering, $mmta_id );
479 ModifyRecordsWithTemplate
481 ModifyRecordsWithTemplate( $template_id, $batch );
483 Accepts a template id and a MARC::Batch object.
486 sub ModifyRecordsWithTemplate {
487 my ( $template_id, $batch ) = @_;
488 C4::Koha::Log( "C4::MarcModificationTemplates::ModifyRecordsWithTemplate( $template_id, $batch )" ) if DEBUG;
489 warn( "C4::MarcModificationTemplates::ModifyRecordsWithTemplate( $template_id, $batch )" ) if DEBUG;
491 while ( my $record = $batch->next() ) {
492 ModifyRecordWithTemplate( $template_id, $record );
497 ModifyRecordWithTemplate
499 ModifyRecordWithTemplate( $template_id, $record )
501 Accepts a MARC::Record object ( $record ) and modifies
502 it based on the actions for the given $template_id
505 sub ModifyRecordWithTemplate {
506 my ( $template_id, $record ) = @_;
507 C4::Koha::Log( "C4::MarcModificationTemplates::ModifyRecordWithTemplate( $template_id, $record )" ) if DEBUG;
508 warn( "C4::MarcModificationTemplates::ModifyRecordWithTemplate( $template_id, $record )" ) if DEBUG;
509 C4::Koha::Log( "Unmodified Record:\n" . $record->as_formatted() ) if DEBUG >= 10;
510 warn( "Unmodified Record:\n" . $record->as_formatted() ) if DEBUG >= 10;
512 my $current_date = DateTime->now()->ymd();
513 my $branchcode = C4::Context->userenv->{branch};
515 my @actions = GetModificationTemplateActions( $template_id );
517 foreach my $a ( @actions ) {
518 my $action = $a->{'action'};
519 my $field_number = $a->{'field_number'};
520 my $from_field = $a->{'from_field'};
521 my $from_subfield = $a->{'from_subfield'};
522 my $field_value = $a->{'field_value'};
523 my $to_field = $a->{'to_field'};
524 my $to_subfield = $a->{'to_subfield'};
525 my $to_regex_search = $a->{'to_regex_search'};
526 my $to_regex_replace = $a->{'to_regex_replace'};
527 my $to_regex_modifiers = $a->{'to_regex_modifiers'};
528 my $conditional = $a->{'conditional'};
529 my $conditional_field = $a->{'conditional_field'};
530 my $conditional_subfield = $a->{'conditional_subfield'};
531 my $conditional_comparison = $a->{'conditional_comparison'};
532 my $conditional_value = $a->{'conditional_value'};
533 my $conditional_regex = $a->{'conditional_regex'};
535 if ( $field_value ) {
536 $field_value =~ s/__CURRENTDATE__/$current_date/g;
537 $field_value =~ s/__BRANCHCODE__/$branchcode/g;
540 my @params = ( $record, $from_field, $from_subfield );
541 if ( $action eq 'update_field' ) {
544 ? ( undef, $field_value )
555 ( ( not $field_value and $to_field )
556 ? ( $to_field, $to_subfield, { search => $to_regex_search, replace => $to_regex_replace, modifiers => $to_regex_modifiers} )
564 if ( $conditional ) {
565 for ( $conditional_comparison ) {
566 when ( /^exists$/ ) {
567 my $exists = field_exists( $record, $conditional_field, $conditional_subfield );
568 $do = $conditional eq 'if'
572 when ( /^not_exists$/ ) {
573 my $exists = field_exists( $record, $conditional_field, $conditional_subfield );
574 $do = $conditional eq 'if'
578 when ( /^equals$/ ) {
579 my $equals = field_equals( $record, $conditional_value, $conditional_field, $conditional_subfield, $conditional_regex );
580 $do = $conditional eq 'if'
584 when ( /^not_equals$/ ) {
585 my $equals = field_equals( $record, $conditional_value, $conditional_field, $conditional_subfield, $conditional_regex );
586 $do = $conditional eq 'if'
595 when ( /^copy_field$/ ) {
596 copy_field( @params );
598 when ( /^update_field$/ ) {
599 update_field( @params );
601 when ( /^move_field$/ ) {
602 move_field( @params );
604 when ( /^delete_field$/ ) {
605 delete_field( @params );
610 C4::Koha::Log( $record->as_formatted() ) if DEBUG >= 10;
611 warn( $record->as_formatted() ) if DEBUG >= 10;