From 8c48ad3785e455591599bae091f36397b55ceb69 Mon Sep 17 00:00:00 2001 From: Jacek Ablewicz Date: Tue, 3 Jun 2014 09:24:23 +0200 Subject: [PATCH] Bug 12343 - TransformKohaToMarc() is adding MARC subfields in random order TransformKohaToMarc() function in C4/Biblio.pm iterates through it's argument - which is a hashref - using 'each'. Perl is not guaranteed to return hash keys in any particular order (not to mention that in more recent perl versions, explicit hash key order randomization is to be expected). As a consequence: 1) For biblio records added via acquisition (order from a new/empty record, order from a suggestion), freshly created MARC biblio records doesn't always have 260 $b and 260 $c stored in the proper order 2) Holdings data exported for zebra indexing as 952 fields may have subfields generated in more-or-less random order. While it probably (?) does not affect zebra indexing/searching in any significant way, end result is prone to be somehow ugly (which can be a potential issue e.g. for people running Z39.50 server) and is not guaranteed to be consistent; different records - or even different items in the same record, can have 952 subfields generated in indiscriminate order. This patch fixes abovementioned issues via introducting explicit sorting (by subfiled code/letter) for subfield pairs before they are added to the MARC record. To test: 1/ Try to confirm and reproduce both issues (use perl 5.18.1 if possible for more randomly ordered results). 2/ Apply patch. 3/ Redo the tests; ensure that both issues are now fixed and that there are no apparent regressions of any kind (especially regarding to 952 fields generated for zebra [re]indexing). Signed-off-by: Chris Cormack --- C4/Biblio.pm | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/C4/Biblio.pm b/C4/Biblio.pm index 60e0069..7e10e69 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -2190,20 +2190,24 @@ sub TransformKohaToMarc { my $record = MARC::Record->new(); SetMarcUnicodeFlag( $record, C4::Context->preference("marcflavour") ); my $db_to_marc = C4::Context->marcfromkohafield; + my $tag_hr = {}; while ( my ($name, $value) = each %$hash ) { next unless my $dtm = $db_to_marc->{''}->{$name}; next unless ( scalar( @$dtm ) ); - my ($tag, $letter) = @$dtm; + my ($tag, $letter) = @$dtm; $tag .= ''; foreach my $value ( split(/\s?\|\s?/, $value, -1) ) { - if ( my $field = $record->field($tag) ) { - $field->add_subfields( $letter => $value ); - } - else { - $record->insert_fields_ordered( MARC::Field->new( - $tag, " ", " ", $letter => $value ) ); - } + $value eq '' && next; + $tag_hr->{$tag} //= []; + push @{$tag_hr->{$tag}}, [($letter, $value)]; } - + } + foreach my $tag (sort keys %$tag_hr) { + my @sfl = @{$tag_hr->{$tag}}; + @sfl = sort { $a->[0] cmp $b->[0]; } @sfl; + @sfl = map { @{$_}; } @sfl; + $record->insert_fields_ordered( + MARC::Field->new($tag, " ", " ", @sfl) + ); } return $record; } -- 1.9.1