From c0f99ba5052e36ec285ce1593f1e6049ca757bd2 Mon Sep 17 00:00:00 2001 From: Jared Camins-Esakov Date: Thu, 30 May 2013 06:23:43 -0400 Subject: [PATCH] Bug 9755 QA follow-up: move MARC-specific functionality to utility class This follow-up moves all the MARC-specific functionality of Koha::Record (now renamed to Koha::MetadataRecord) to a Koha::Util::MARC utility class. To test, run relevant unit tests: > prove t/Koha_MetadataRecord.t t/Koha_Util_MARC.t t/db_dependent/Koha_Authority.t and optionally try to merge a record. Filtered Filtered f6b051d4b180ca8882626bd6adfc7bb98eb97550 Signed-off-by: Jared Camins-Esakov http://bugs.koha-community.org/show_bug.cgi?id=6473 Signed-off-by: Jared Camins-Esakov Signed-off-by: Jared Camins-Esakov Signed-off-by: Jared Camins-Esakov Signed-off-by: Jared Camins-Esakov Signed-off-by: Jared Camins-Esakov Signed-off-by: Jared Camins-Esakov Signed-off-by: Jared Camins-Esakov --- Koha/Authority.pm | 11 ++-- Koha/MetadataRecord.pm | 59 +++++++++++++++++ Koha/Record.pm | 115 --------------------------------- Koha/Util/MARC.pm | 110 +++++++++++++++++++++++++++++++ cataloguing/merge.pl | 10 +-- t/Koha_MetadataRecord.t | 98 ++++++++++++++++++++++++++++ t/{Koha_Record.t => Koha_Util_MARC.t} | 14 ++-- 7 files changed, 285 insertions(+), 132 deletions(-) create mode 100644 Koha/MetadataRecord.pm delete mode 100644 Koha/Record.pm create mode 100644 Koha/Util/MARC.pm create mode 100755 t/Koha_MetadataRecord.t rename t/{Koha_Record.t => Koha_Util_MARC.t} (90%) diff --git a/Koha/Authority.pm b/Koha/Authority.pm index 855ce1f..509fe3f 100644 --- a/Koha/Authority.pm +++ b/Koha/Authority.pm @@ -38,9 +38,9 @@ use MARC::Record; use MARC::File::XML; use C4::Charset; -use base qw(Koha::Record); +use base qw(Koha::MetadataRecord); -__PACKAGE__->mk_accessors(qw( authid authtype marcflavour )); +__PACKAGE__->mk_accessors(qw( authid authtype )); =head2 new @@ -65,12 +65,15 @@ sub new { my $auth = Koha::Authority->get_from_authid($authid); Create the Koha::Authority object associated with the provided authid. +Note that this routine currently retrieves a MARC record because +authorities in Koha are MARC records by definition. This is an +unfortunate but unavoidable fact. =cut sub get_from_authid { my $class = shift; my $authid = shift; - my $marcflavour = C4::Context->preference("marcflavour"); + my $marcflavour = lc C4::Context->preference("marcflavour"); my $dbh=C4::Context->dbh; my $sth=$dbh->prepare("select authtypecode, marcxml from auth_header where authid=?"); @@ -82,8 +85,8 @@ sub get_from_authid { $record->encoding('UTF-8'); my $self = $class->SUPER::new( { authid => $authid, - marcflavour => $marcflavour, authtype => $authtypecode, + schema => $marcflavour, record => $record }); bless $self, $class; diff --git a/Koha/MetadataRecord.pm b/Koha/MetadataRecord.pm new file mode 100644 index 0000000..865dc0d --- /dev/null +++ b/Koha/MetadataRecord.pm @@ -0,0 +1,59 @@ +package Koha::MetadataRecord; + +# Copyright 2013 C & P Bibliography Services +# +# 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 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. +# +# 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. + +=head1 NAME + +Koha::MetadataRecord - base class for metadata records + +=head1 SYNOPSIS + + my $record = new Koha::MetadataRecord({ 'record' => $marcrecord }); + +=head1 DESCRIPTION + +Object-oriented class that encapsulates all metadata (i.e. bibliographic +and authority) records in Koha. + +=cut + +use strict; +use warnings; +use C4::Context; +use Koha::Util::MARC; + +use base qw(Class::Accessor); + +__PACKAGE__->mk_accessors(qw( record schema )); + + +=head2 createMergeHash + +Create a hash for use when merging records. At the moment the only +metadata schema supported is MARC. + +=cut + +sub createMergeHash { + my ($self, $tagslib) = @_; + if ($self->schema =~ m/marc/) { + return Koha::Util::MARC::createMergeHash($self->record, $tagslib); + } +} + +1; diff --git a/Koha/Record.pm b/Koha/Record.pm deleted file mode 100644 index 1e3c7a3..0000000 --- a/Koha/Record.pm +++ /dev/null @@ -1,115 +0,0 @@ -package Koha::Record; - -# Copyright 2013 C & P Bibliography Services -# -# 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 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. -# -# 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. - -=head1 NAME - -Koha::Record - base class for MARC records - -=head1 SYNOPSIS - - my $record = new Koha::Record({ 'record' => $marcrecord }); - -=head1 DESCRIPTION - -Object-oriented class that encapsulates all records in Koha. - -=cut - -use strict; -use warnings; -use C4::Context; -use MARC::Record; - -use base qw(Class::Accessor); - -__PACKAGE__->mk_accessors(qw( record marcflavour )); - - -=head2 createMarcHash - -Create a MARC hash for use when merging records. - -=cut - -sub createMarcHash { - my ($self, $tagslib) = @_; - my $record = $self->record; - my @array; - my @fields = $record->fields(); - - - foreach my $field (@fields) { - my $fieldtag = $field->tag(); - if ($fieldtag < 10) { - if (!defined($tagslib) || $tagslib->{$fieldtag}->{'@'}->{'tab'} >= 0) { - push @array, { - field => [ - { - tag => $fieldtag, - key => _createKey(), - value => $field->data(), - } - ] - }; - } - } else { - my @subfields = $field->subfields(); - my @subfield_array; - foreach my $subfield (@subfields) { - if (!defined($tagslib) || $tagslib->{$fieldtag}->{@$subfield[0]}->{'tab'} >= 0) { - push @subfield_array, { - subtag => @$subfield[0], - subkey => _createKey(), - value => @$subfield[1], - }; - } - - } - - if ((!defined($tagslib) || $tagslib->{$fieldtag}->{'tab'} >= 0) && $fieldtag ne '995' && $fieldtag ne '999') { - push @array, { - field => [ - { - tag => $fieldtag, - key => _createKey(), - indicator1 => $field->indicator(1), - indicator2 => $field->indicator(2), - subfield => [@subfield_array], - } - ] - }; - } - - } - } - return [@array]; - -} - -=head2 _createKey - -Create a random value to set it into the input name - -=cut - -sub _createKey { - return int(rand(1000000)); -} - -1; diff --git a/Koha/Util/MARC.pm b/Koha/Util/MARC.pm new file mode 100644 index 0000000..e8ec125 --- /dev/null +++ b/Koha/Util/MARC.pm @@ -0,0 +1,110 @@ +package Koha::Util::MARC; + +# Copyright 2013 C & P Bibliography Services +# +# 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 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. +# +# 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 Modern::Perl; +use MARC::Record; + +=head1 NAME + +Koha::Util::MARC - utility class with routines for working with MARC records + +=head1 METHODS + +=head2 createMergeHash + +Create a hash to use when merging MARC records + +=cut + +sub createMergeHash { + my ( $record, $tagslib ) = @_; + + return unless $record; + + my @array; + my @fields = $record->fields(); + + foreach my $field (@fields) { + my $fieldtag = $field->tag(); + if ( $fieldtag < 10 ) { + if ( !defined($tagslib) + || $tagslib->{$fieldtag}->{'@'}->{'tab'} >= 0 ) + { + push @array, + { + field => [ + { + tag => $fieldtag, + key => _createKey(), + value => $field->data(), + } + ] + }; + } + } + else { + my @subfields = $field->subfields(); + my @subfield_array; + foreach my $subfield (@subfields) { + if ( !defined($tagslib) + || $tagslib->{$fieldtag}->{ @$subfield[0] }->{'tab'} >= 0 ) + { + push @subfield_array, + { + subtag => @$subfield[0], + subkey => _createKey(), + value => @$subfield[1], + }; + } + + } + + if ( ( !defined($tagslib) || $tagslib->{$fieldtag}->{'tab'} >= 0 ) + && @subfield_array ) + { + push @array, + { + field => [ + { + tag => $fieldtag, + key => _createKey(), + indicator1 => $field->indicator(1), + indicator2 => $field->indicator(2), + subfield => [@subfield_array], + } + ] + }; + } + + } + } + return [@array]; +} + +=head2 _createKey + +Create a random value to set it into the input name + +=cut + +sub _createKey { + return int(rand(1000000)); +} + +1; diff --git a/cataloguing/merge.pl b/cataloguing/merge.pl index 0fc4f52..e24b767 100755 --- a/cataloguing/merge.pl +++ b/cataloguing/merge.pl @@ -30,7 +30,7 @@ use C4::Serials; use C4::Koha; use C4::Reserves qw/MergeHolds/; use C4::Acquisition qw/ModOrder GetOrdersByBiblionumber/; -use Koha::Record; +use Koha::MetadataRecord; my $input = new CGI; my @biblionumber = $input->param('biblionumber'); @@ -170,11 +170,11 @@ if ($merge) { # Creating a loop for display - my $recordObj1 = new Koha::Record({ 'record' => GetMarcBiblio($mergereference) }); - my $recordObj2 = new Koha::Record({ 'record' => GetMarcBiblio($notreference) }); + my $recordObj1 = new Koha::MetadataRecord({ 'record' => GetMarcBiblio($mergereference), 'schema' => lc C4::Context->preference('marcflavour') }); + my $recordObj2 = new Koha::MetadataRecord({ 'record' => GetMarcBiblio($notreference), 'schema' => lc C4::Context->preference('marcflavour') }); - my @record1 = $recordObj1->createMarcHash($tagslib); - my @record2 = $recordObj2->createMarcHash($tagslib); + my @record1 = $recordObj1->createMergeHash($tagslib); + my @record2 = $recordObj2->createMergeHash($tagslib); # Parameters $template->param( diff --git a/t/Koha_MetadataRecord.t b/t/Koha_MetadataRecord.t new file mode 100755 index 0000000..53f25a1 --- /dev/null +++ b/t/Koha_MetadataRecord.t @@ -0,0 +1,98 @@ +#!/usr/bin/perl + +# Copyright 2013 C & P Bibliography Services +# +# 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 Test::More tests => 4; + +BEGIN { + use_ok('Koha::MetadataRecord'); +} + +my $marcrecord = MARC::Record->new; + +$marcrecord->add_fields( + [ '001', '1234' ], + [ '150', ' ', ' ', a => 'Cooking' ], + [ '450', ' ', ' ', a => 'Cookery', z => 'Instructional manuals' ], + ); +my $record = Koha::MetadataRecord->new({ 'record' => $marcrecord, 'schema' => 'marc21' }); + +is(ref($record), 'Koha::MetadataRecord', 'Created valid Koha::MetadataRecord object'); + +my $samplehash = [ + { + 'field' => [ + { + 'value' => '1234', + 'tag' => '001', + } + ] + }, + { + 'field' => [ + { + 'subfield' => [ + { + 'value' => 'Cooking', + 'subtag' => 'a' + } + ], + 'indicator2' => ' ', + 'tag' => 150, + 'indicator1' => ' ', + } + ] + }, + { + 'field' => [ + { + 'subfield' => [ + { + 'value' => 'Cookery', + 'subtag' => 'a' + }, + { + 'value' => 'Instructional manuals', + 'subtag' => 'z' + } + ], + 'indicator2' => ' ', + 'tag' => 450, + 'indicator1' => ' ', + } + ] + } +]; + +my $hash = $record->createMergeHash(); +my %fieldkeys; +foreach my $field (@$hash) { + $fieldkeys{delete $field->{'field'}->[0]->{'key'}}++; + if (defined $field->{'field'}->[0]->{'subfield'}) { + foreach my $subfield (@{$field->{'field'}->[0]->{'subfield'}}) { + $fieldkeys{delete $subfield->{'subkey'}}++; + } + } +} + +is_deeply($hash, $samplehash, 'Generated hash correctly'); +my $dupkeys = grep { $_ > 1 } values %fieldkeys; +is($dupkeys, 0, 'No duplicate keys'); diff --git a/t/Koha_Record.t b/t/Koha_Util_MARC.t similarity index 90% rename from t/Koha_Record.t rename to t/Koha_Util_MARC.t index ca9a246..797fc34 100755 --- a/t/Koha_Record.t +++ b/t/Koha_Util_MARC.t @@ -17,13 +17,16 @@ # with Koha; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# Note that at present this test is almost identical to the one testing +# the encapsulating method in Koha::MetadataRecord. + use strict; use warnings; -use Test::More tests => 4; +use Test::More tests => 3; BEGIN { - use_ok('Koha::Record'); + use_ok('Koha::Util::MARC'); } my $marcrecord = MARC::Record->new; @@ -33,10 +36,6 @@ $marcrecord->add_fields( [ '150', ' ', ' ', a => 'Cooking' ], [ '450', ' ', ' ', a => 'Cookery', z => 'Instructional manuals' ], ); -my $record = Koha::Record->new({ 'record' => $marcrecord }); - -is(ref($record), 'Koha::Record', 'Created valid Koha::Record object'); - my $samplehash = [ { 'field' => [ @@ -82,9 +81,8 @@ my $samplehash = [ } ]; -my $hash = $record->createMarcHash(); +my $hash = Koha::Util::MARC::createMergeHash($marcrecord); my %fieldkeys; -require Data::Dumper; foreach my $field (@$hash) { $fieldkeys{delete $field->{'field'}->[0]->{'key'}}++; if (defined $field->{'field'}->[0]->{'subfield'}) { -- 1.7.9.5