From cfbfe040046411fdcb6fe395bf587ddb904a596a Mon Sep 17 00:00:00 2001
From: Jared Camins-Esakov <jcamins@cpbibliography.com>
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 <jcamins@cpbibliography.com>

http://bugs.koha-community.org/show_bug.cgi?id=6473
Signed-off-by: Jared Camins-Esakov <jcamins@cpbibliography.com>
Signed-off-by: Jared Camins-Esakov <jcamins@cpbibliography.com>
---
 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