From 8528376c9d0828581ff0ff38f9411280273762bf Mon Sep 17 00:00:00 2001 From: Ere Maijala Date: Mon, 27 Aug 2018 15:07:12 +0300 Subject: [PATCH] Bug 20447: Include basic summary holdings in the OAI-PMH responses. https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=20447 If include_items is set in oai conf, also basic location information from holdings records is included in the returned MARC records. --- C4/Biblio.pm | 25 +++++++++++++++ C4/Holdings.pm | 75 +++++++++++++++++++++++++++++++++++++++++++ Koha/OAI/Server/Repository.pm | 1 + 3 files changed, 101 insertions(+) diff --git a/C4/Biblio.pm b/C4/Biblio.pm index 447ef96..c5d8d51 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -366,6 +366,24 @@ sub _strip_item_fields { } } +=head2 _strip_holdings_fields + + _strip_holdings_fields($record) + +Utility routine to remove holdings tags from a +MARC bib. + +=cut + +sub _strip_holdings_fields { + my $record = shift; + my $frameworkcode = shift; + my ( $holdingstag ) = GetMarcFromKohaField( "holdings.holdingbranch" ); + foreach my $field ( $record->field($holdingstag) ) { + $record->delete_field($field); + } +} + =head2 DelBiblio my $error = &DelBiblio($biblionumber); @@ -2809,6 +2827,13 @@ sub EmbedItemsInMarcBiblio { $itemnumbers = [] unless defined $itemnumbers; + if ( C4::Context->preference('SummaryHoldings') && !@$itemnumbers ) { + _strip_holdings_fields($marc); + require C4::Holdings; + my $holdings_fields = C4::Holdings::GetMarcHoldingsFields( $biblionumber ); + $marc->append_fields(@$holdings_fields) if ( @$holdings_fields ); + } + my $frameworkcode = GetFrameworkCode($biblionumber); _strip_item_fields($marc, $frameworkcode); diff --git a/C4/Holdings.pm b/C4/Holdings.pm index 7e13b01..ff1087b 100644 --- a/C4/Holdings.pm +++ b/C4/Holdings.pm @@ -415,6 +415,35 @@ sub GetMarcHoldingsByBiblionumber { return \@records; } +=head2 GetMarcHoldingsFields + + my @marc_fields = GetMarcHoldingsFields($biblionumber); + +Returns an array of MARC::Record objects of the holdings for the biblio. + +=cut + +sub GetMarcHoldingsFields { + my ( $biblionumber ) = @_; + # This is so much faster than using Koha::Holdings->search that it makes sense even if it's ugly. + my $sth = C4::Context->dbh->prepare( 'SELECT * FROM holdings WHERE biblionumber = ?' ); + $sth->execute( $biblionumber ); + my $holdings = $sth->fetchall_arrayref({}); + $sth->finish(); + my @holdings_fields; + my ( $holdingstag, $holdingssubfield ) = GetMarcHoldingFromKohaField( 'holdings.holdingbranch' ); + ITEMLOOP: foreach my $holding (@$holdings) { + my $mungedholding = { + map { + defined($holding->{$_}) && $holding->{$_} ne '' ? ("holdings.$_" => $holding->{$_}) : () + } keys %{ $holding } + }; + my $marc = TransformKohaHoldingToMarc($mungedholding); + push @holdings_fields, $marc->field( $holdingstag ); + } + return \@holdings_fields; +} + =head2 GetHoldingFrameworkCode $frameworkcode = GetFrameworkCode( $holding_id ) @@ -773,6 +802,52 @@ sub TransformMarcHoldingToKohaOneField { return $retval; } +=head2 TransformKohaToMarc + + $record = TransformKohaToMarc( $hash [, $params ] ) + +This function builds partial MARC::Record from holdings hash entries. +This function is called when embedding holdings into a biblio record. + +=cut + +sub TransformKohaHoldingToMarc { + my ( $hash, $params ) = @_; + my $record = MARC::Record->new(); + SetMarcUnicodeFlag( $record, C4::Context->preference("marcflavour") ); + + # In the next call we use the Default holdings framework, since it is considered + # authoritative for Koha to Marc mappings. + my $mss = C4::Biblio::GetMarcSubfieldStructure( 'HLD', { unsafe => 1 } ); # do not change framewok + my $tag_hr = {}; + while ( my ($kohafield, $value) = each %$hash ) { + foreach my $fld ( @{ $mss->{$kohafield} } ) { + my $tagfield = $fld->{tagfield}; + my $tagsubfield = $fld->{tagsubfield}; + next if !$tagfield; + my @values = $params->{no_split} + ? ( $value ) + : split(/\s?\|\s?/, $value, -1); + foreach my $value ( @values ) { + next if $value eq ''; + $tag_hr->{$tagfield} //= []; + push @{$tag_hr->{$tagfield}}, [($tagsubfield, $value)]; + } + } + } + foreach my $tag (sort keys %$tag_hr) { + my @sfl = @{$tag_hr->{$tag}}; + @sfl = sort { $a->[0] cmp $b->[0]; } @sfl; + @sfl = map { @{$_}; } @sfl; + # Special care for control fields: remove the subfield indication @ + # and do not insert indicators. + my @ind = $tag < 10 ? () : ( " ", " " ); + @sfl = grep { $_ ne '@' } @sfl if $tag < 10; + $record->insert_fields_ordered( MARC::Field->new($tag, @ind, @sfl) ); + } + return $record; +} + 1; diff --git a/Koha/OAI/Server/Repository.pm b/Koha/OAI/Server/Repository.pm index 30ace36..e95200d 100644 --- a/Koha/OAI/Server/Repository.pm +++ b/Koha/OAI/Server/Repository.pm @@ -93,6 +93,7 @@ mode. A configuration file koha-oai.conf can look like that: xsl_file: /usr/local/koha/koha-tmpl/intranet-tmpl/xslt/UNIMARCslim2OAIDC.xsl Note the 'include_items' parameter which is the only mean to return item-level info. +If summary holdings are enabled, 'include_items' includes their location information too. =cut -- 2.7.4