From 0c4495ecd6f5d34eddda35bf897cb27fc5c46f44 Mon Sep 17 00:00:00 2001 From: Agustin Moyano Date: Mon, 27 Feb 2023 19:10:31 -0300 Subject: [PATCH] Bug 33083: Add a generic class to handle methods for collections of records To test: 1. Apply patch 2. prove t/db_dependent/Koha/Objects/Record/Collections.t --- Koha/Authorities.pm | 2 +- Koha/Biblio.pm | 14 +++ Koha/Biblios.pm | 2 +- Koha/Objects/Record/Collections.pm | 94 +++++++++++++++++++ t/db_dependent/Biblio.t | 17 +++- .../Koha/Objects/Record/Collections.t | 57 +++++++++++ 6 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 Koha/Objects/Record/Collections.pm create mode 100755 t/db_dependent/Koha/Objects/Record/Collections.t diff --git a/Koha/Authorities.pm b/Koha/Authorities.pm index a509b75fa2..9d29346787 100644 --- a/Koha/Authorities.pm +++ b/Koha/Authorities.pm @@ -24,7 +24,7 @@ use Koha::Database; use Koha::Authority; -use base qw(Koha::Objects); +use base qw(Koha::Objects Koha::Objects::Record::Collections); =head1 NAME diff --git a/Koha/Biblio.pm b/Koha/Biblio.pm index 5bf369cd6a..c74b6ac556 100644 --- a/Koha/Biblio.pm +++ b/Koha/Biblio.pm @@ -88,6 +88,20 @@ sub metadata { return Koha::Biblio::Metadata->_new_from_dbic($metadata); } +=head3 record + +my $record = $biblio->record(); + +Returns a Marc::Record object + +=cut + +sub record { + my ( $self ) = @_; + + return $self->metadata->record; +} + =head3 orders my $orders = $biblio->orders(); diff --git a/Koha/Biblios.pm b/Koha/Biblios.pm index 416aa2bbe5..cf1cbdb83a 100644 --- a/Koha/Biblios.pm +++ b/Koha/Biblios.pm @@ -25,7 +25,7 @@ use Koha::Database; use Koha::Biblio; use Koha::Libraries; -use base qw(Koha::Objects); +use base qw(Koha::Objects Koha::Objects::Record::Collections); =head1 NAME diff --git a/Koha/Objects/Record/Collections.pm b/Koha/Objects/Record/Collections.pm new file mode 100644 index 0000000000..4be5b8e387 --- /dev/null +++ b/Koha/Objects/Record/Collections.pm @@ -0,0 +1,94 @@ +package Koha::Objects::Record::Collections; + +# Copyright 2023 Theke Solutions +# +# 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, see . + +use Modern::Perl; + +use MARC::File::MiJ; +use MARC::File::USMARC; +use MARC::File::XML; +use MARC::Record; + +=head1 NAME + +Koha::Objects::Record::Collections - Generic records collection handling class + +=head1 SYNOPSIS + + use base qw(Koha::Objects Koha::Objects::Record::Collections); + my $collections = Koha::Objects->print_collection($format); + +=head1 DESCRIPTION + +This class is provided as a generic way of handling a collection of records for Koha::Objects-based classes +in Koha. + +This class must always be subclassed. + +=head1 API + +=head2 Class methods + +=cut + +=head3 print_collection + my $collection_text = $result_set->print_collection($format) + +Return a text representation of a collection (group of records) in the specified format. +Allowed formats are marcxml, mij, marc and txt. Defaults to marcxml. + +=cut + +sub print_collection { + my ( $self, $format ) = @_; + + my ( $start, $glue, $end, @parts ); + + my %serializers = ( + 'mij' => \&MARC::File::MiJ::encode, + 'marc' => \&MARC::File::USMARC::encode, + 'txt' => \&MARC::Record::as_formatted, + 'marcxml' => \&MARC::File::XML::record + ); + if ( $format eq 'mij' ) { + $start = '['; + $glue = ','; + $end = ']'; + } + elsif ( $format eq 'marc' ) { + $glue = "\n"; + } + elsif ( $format eq 'txt' ) { + $glue = "\n\n"; + } + else { + $glue = ''; + $format = 'marcxml'; + $start = MARC::File::XML::header(); + $end = MARC::File::XML::footer(); + } + while ( my $element = $self->next ) { + push @parts, $serializers{$format}->( $element->record ); + } + return + ( defined $start ? $start : '' ) + . join( $glue, @parts ) + . ( defined $end ? $end : '' ); +} + +1; diff --git a/t/db_dependent/Biblio.t b/t/db_dependent/Biblio.t index 67cba63c4f..ab8c2f6d43 100755 --- a/t/db_dependent/Biblio.t +++ b/t/db_dependent/Biblio.t @@ -17,7 +17,7 @@ use Modern::Perl; -use Test::More tests => 15; +use Test::More tests => 16; use Test::MockModule; use Test::Warn; use List::MoreUtils qw( uniq ); @@ -852,6 +852,21 @@ subtest 'autoControlNumber tests' => sub { }; +subtest 'record test' => sub { + plan tests => 1; + + my $marc_record = MARC::Record->new; + $marc_record->append_fields( create_isbn_field( '0590353403', 'MARC21' ) ); + + my ($biblionumber) = C4::Biblio::AddBiblio( $marc_record, '' ); + + my $biblio = Koha::Biblios->find($biblionumber); + + is( $biblio->record->as_formatted, + $biblio->metadata->record->as_formatted ); +}; + + # Cleanup Koha::Caches->get_instance->clear_from_cache( "MarcSubfieldStructure-" ); diff --git a/t/db_dependent/Koha/Objects/Record/Collections.t b/t/db_dependent/Koha/Objects/Record/Collections.t new file mode 100755 index 0000000000..a6c26c261f --- /dev/null +++ b/t/db_dependent/Koha/Objects/Record/Collections.t @@ -0,0 +1,57 @@ +#!/usr/bin/env perl + +use Modern::Perl; + +use Test::More tests => 1; + +use Koha::Biblios; +use Koha::Database; +use JSON qw( decode_json ); + +use t::lib::TestBuilder; + +my $schema = Koha::Database->new->schema; +my $builder = t::lib::TestBuilder->new; + +subtest 'print_collection() tests' => sub { + plan tests => 4; + + $schema->storage->txn_begin; + + # Two biblios + my $biblio_1 = $builder->build_sample_biblio; + my $biblio_2 = $builder->build_sample_biblio; + + my $result_set = Koha::Biblios->search( + [ + { biblionumber => $biblio_1->biblionumber }, + { biblionumber => $biblio_2->biblionumber } + ] + ); + my $collection = $result_set->print_collection('marcxml'); + + like( $collection, qr/<(\s*\w*:)?collection[^>]*>/, 'Has collection tag' ); + + $result_set->reset; + $collection = $result_set->print_collection('mij'); + + my $count = scalar( @{ decode_json($collection) } ); + + is( $count, 2, 'Has 2 elements' ); + + $result_set->reset; + $collection = $result_set->print_collection('marc'); + + $count = $collection =~ tr/[\x1D]//; + + is( $count, 2, 'Has 2 USMARC end of record' ); + + $result_set->reset; + $collection = $result_set->print_collection('txt'); + + $count = scalar( split( /\n\n/, $collection ) ); + + is( $count, 2, 'Has 2 records' ); + + $schema->storage->txn_rollback; +}; -- 2.30.2