X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=C4%2FBiblio.pm;h=96baaef42b88b0f3a7a1da6fd0e45e438b975bb0;hb=a7a4d39697bf52ad805fadd53d388b4530568774;hp=8ea5da5bc4b425d279a034ee374b76d2e462acfc;hpb=bdd0e225bc291280cc40b4a8326a33a21638338b;p=koha_fer diff --git a/C4/Biblio.pm b/C4/Biblio.pm index 8ea5da5bc4..96baaef42b 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -1,6 +1,8 @@ package C4::Biblio; # Copyright 2000-2002 Katipo Communications +# Copyright 2010 BibLibre +# Copyright 2011 Equinox Software, Inc. # # This file is part of Koha. # @@ -19,6 +21,7 @@ package C4::Biblio; use strict; use warnings; +use Carp; # use utf8; use MARC::Record; @@ -34,6 +37,7 @@ use C4::ClassSource; use C4::Charset; require C4::Heading; require C4::Serials; +require C4::Items; use vars qw($VERSION @ISA @EXPORT); @@ -78,6 +82,8 @@ BEGIN { &GetUsedMarcStructure &GetXmlBiblio &GetCOinSBiblio + &GetMarcPrice + &GetMarcQuantity &GetAuthorisedValueDesc &GetMarcStructure @@ -249,6 +255,7 @@ sub AddBiblio { my $dbh = C4::Context->dbh; # transform the data into koha-table style data + SetUTF8Flag($record); my $olddata = TransformMarcToKoha( $dbh, $record, $frameworkcode ); ( $biblionumber, $error ) = _koha_add_biblio( $dbh, $olddata, $frameworkcode ); $olddata->{'biblionumber'} = $biblionumber; @@ -288,52 +295,30 @@ and biblionumber data for indexing. sub ModBiblio { my ( $record, $biblionumber, $frameworkcode ) = @_; + croak "No record" unless $record; + if ( C4::Context->preference("CataloguingLog") ) { my $newrecord = GetMarcBiblio($biblionumber); logaction( "CATALOGUING", "MODIFY", $biblionumber, "BEFORE=>" . $newrecord->as_formatted ); } - my $dbh = C4::Context->dbh; - - $frameworkcode = "" unless $frameworkcode; - - # get the items before and append them to the biblio before updating the record, atm we just have the biblio - my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField( "items.itemnumber", $frameworkcode ); - my $oldRecord = GetMarcBiblio($biblionumber); - - # delete any item fields from incoming record to avoid - # duplication or incorrect data - use AddItem() or ModItem() - # to change items - foreach my $field ( $record->field($itemtag) ) { - $record->delete_field($field); - } - - # parse each item, and, for an unknown reason, re-encode each subfield - # if you don't do that, the record will have encoding mixed - # and the biblio will be re-encoded. - # strange, I (Paul P.) searched more than 1 day to understand what happends - # but could only solve the problem this way... - my @fields = $oldRecord->field($itemtag); - foreach my $fielditem (@fields) { - my $field; - foreach ( $fielditem->subfields() ) { - if ($field) { - $field->add_subfields( Encode::encode( 'utf-8', $_->[0] ) => Encode::encode( 'utf-8', $_->[1] ) ); - } else { - $field = MARC::Field->new( "$itemtag", '', '', Encode::encode( 'utf-8', $_->[0] ) => Encode::encode( 'utf-8', $_->[1] ) ); - } - } - $record->append_fields($field); - } - + # Cleaning up invalid fields must be done early or SetUTF8Flag is liable to + # throw an exception which probably won't be handled. foreach my $field ($record->fields()) { if (! $field->is_control_field()) { - if (scalar($field->subfields()) == 0) { - $record->delete_fields($field); + if (scalar($field->subfields()) == 0 || (scalar($field->subfields()) == 1 && $field->subfield('9'))) { + $record->delete_field($field); } } } + SetUTF8Flag($record); + my $dbh = C4::Context->dbh; + + $frameworkcode = "" unless $frameworkcode; + + _strip_item_fields($record, $frameworkcode); + # update biblionumber and biblioitemnumber in MARC # FIXME - this is assuming a 1 to 1 relationship between # biblios and biblioitems @@ -358,6 +343,29 @@ sub ModBiblio { return 1; } +=head2 _strip_item_fields + + _strip_item_fields($record, $frameworkcode) + +Utility routine to remove item tags from a +MARC bib. + +=cut + +sub _strip_item_fields { + my $record = shift; + my $frameworkcode = shift; + # get the items before and append them to the biblio before updating the record, atm we just have the biblio + my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField( "items.itemnumber", $frameworkcode ); + + # delete any item fields from incoming record to avoid + # duplication or incorrect data - use AddItem() or ModItem() + # to change items + foreach my $field ( $record->field($itemtag) ) { + $record->delete_field($field); + } +} + =head2 ModBiblioframework ModBiblioframework($biblionumber,$frameworkcode); @@ -750,12 +758,13 @@ Return the ISBD view which can be included in opac and intranet sub GetISBDView { my ( $biblionumber, $template ) = @_; - my $record = GetMarcBiblio($biblionumber); + my $record = GetMarcBiblio($biblionumber, 1); + return undef unless defined $record; my $itemtype = &GetFrameworkCode($biblionumber); my ( $holdingbrtagf, $holdingbrtagsubf ) = &GetMarcFromKohaField( "items.holdingbranch", $itemtype ); my $tagslib = &GetMarcStructure( 1, $itemtype ); - my $ISBD = C4::Context->preference('ISBD'); + my $ISBD = C4::Context->preference('isbd'); my $bloc = $ISBD; my $res; my $blocres; @@ -1036,16 +1045,18 @@ sub GetMarcFromKohaField { =head2 GetMarcBiblio - my $record = GetMarcBiblio($biblionumber); + my $record = GetMarcBiblio($biblionumber, [$embeditems]); Returns MARC::Record representing bib identified by C<$biblionumber>. If no bib exists, returns undef. -The MARC record contains both biblio & item data. +C<$embeditems>. If set to true, items data are included. +The MARC record contains biblio data, and items data if $embeditems is set to true. =cut sub GetMarcBiblio { my $biblionumber = shift; + my $embeditems = shift || 0; my $dbh = C4::Context->dbh; my $sth = $dbh->prepare("SELECT marcxml FROM biblioitems WHERE biblionumber=? "); $sth->execute($biblionumber); @@ -1057,6 +1068,9 @@ sub GetMarcBiblio { if ($marcxml) { $record = eval { MARC::Record::new_from_xml( $marcxml, "utf8", C4::Context->preference('marcflavour') ) }; if ($@) { warn " problem with :$biblionumber : $@ \n$marcxml"; } + return unless $record; + + C4::Biblio::EmbedItemsInMarcBiblio($record, $biblionumber) if ($embeditems); # $record = MARC::Record::new_from_usmarc( $marc) if $marc; return $record; @@ -1113,54 +1127,61 @@ sub GetCOinSBiblio { my $isbn = ''; my $issn = ''; my $publisher = ''; - - if ( C4::Context->preference("marcflavour") eq "UNIMARC" ) { - my $fmts6; - my $fmts7; - %$fmts6 = ( - 'a' => 'book', - 'b' => 'manuscript', - 'c' => 'book', - 'd' => 'manuscript', - 'e' => 'map', - 'f' => 'map', - 'g' => 'film', - 'i' => 'audioRecording', - 'j' => 'audioRecording', - 'k' => 'artwork', - 'l' => 'document', - 'm' => 'computerProgram', - 'r' => 'document', - - ); - %$fmts7 = ( - 'a' => 'journalArticle', - 's' => 'journal', - ); - - $genre = $fmts6->{$pos6} ? $fmts6->{$pos6} : 'book'; - - if ( $genre eq 'book' ) { + my $pages = ''; + my $titletype = 'b'; + + # For the purposes of generating COinS metadata, LDR/06-07 can be + # considered the same for UNIMARC and MARC21 + my $fmts6; + my $fmts7; + %$fmts6 = ( + 'a' => 'book', + 'b' => 'manuscript', + 'c' => 'book', + 'd' => 'manuscript', + 'e' => 'map', + 'f' => 'map', + 'g' => 'film', + 'i' => 'audioRecording', + 'j' => 'audioRecording', + 'k' => 'artwork', + 'l' => 'document', + 'm' => 'computerProgram', + 'o' => 'document', + 'r' => 'document', + ); + %$fmts7 = ( + 'a' => 'journalArticle', + 's' => 'journal', + ); + + $genre = $fmts6->{$pos6} ? $fmts6->{$pos6} : 'book'; + + if ( $genre eq 'book' ) { $genre = $fmts7->{$pos7} if $fmts7->{$pos7}; - } + } - ##### We must transform mtx to a valable mtx and document type #### - if ( $genre eq 'book' ) { + ##### We must transform mtx to a valable mtx and document type #### + if ( $genre eq 'book' ) { $mtx = 'book'; - } elsif ( $genre eq 'journal' ) { + } elsif ( $genre eq 'journal' ) { $mtx = 'journal'; - } elsif ( $genre eq 'journalArticle' ) { + $titletype = 'j'; + } elsif ( $genre eq 'journalArticle' ) { $mtx = 'journal'; $genre = 'article'; - } else { + $titletype = 'a'; + } else { $mtx = 'dc'; - } + } - $genre = ( $mtx eq 'dc' ) ? "&rft.type=$genre" : "&rft.genre=$genre"; + $genre = ( $mtx eq 'dc' ) ? "&rft.type=$genre" : "&rft.genre=$genre"; + + if ( C4::Context->preference("marcflavour") eq "UNIMARC" ) { # Setting datas - $aulast = $record->subfield( '700', 'a' ); - $aufirst = $record->subfield( '700', 'b' ); + $aulast = $record->subfield( '700', 'a' ) || ''; + $aufirst = $record->subfield( '700', 'b' ) || ''; $oauthors = "&rft.au=$aufirst $aulast"; # others authors @@ -1173,16 +1194,13 @@ sub GetCOinSBiblio { ( $mtx eq 'dc' ) ? "&rft.title=" . $record->subfield( '200', 'a' ) : "&rft.title=" . $record->subfield( '200', 'a' ) . "&rft.btitle=" . $record->subfield( '200', 'a' ); - $pubyear = $record->subfield( '210', 'd' ); - $publisher = $record->subfield( '210', 'c' ); - $isbn = $record->subfield( '010', 'a' ); - $issn = $record->subfield( '011', 'a' ); + $pubyear = $record->subfield( '210', 'd' ) || ''; + $publisher = $record->subfield( '210', 'c' ) || ''; + $isbn = $record->subfield( '010', 'a' ) || ''; + $issn = $record->subfield( '011', 'a' ) || ''; } else { # MARC21 need some improve - my $fmts; - $mtx = 'book'; - $genre = "&rft.genre=book"; # Setting datas if ( $record->field('100') ) { @@ -1195,17 +1213,34 @@ sub GetCOinSBiblio { $oauthors .= "&rft.au=$au"; } } - $title = "&rft.btitle=" . $record->subfield( '245', 'a' ); + $title = "&rft." . $titletype . "title=" . $record->subfield( '245', 'a' ); $subtitle = $record->subfield( '245', 'b' ) || ''; $title .= $subtitle; - $pubyear = $record->subfield( '260', 'c' ) || ''; - $publisher = $record->subfield( '260', 'b' ) || ''; - $isbn = $record->subfield( '020', 'a' ) || ''; - $issn = $record->subfield( '022', 'a' ) || ''; + if ($titletype eq 'a') { + $pubyear = substr $record->field('008')->data(), 7, 4; + $isbn = $record->subfield( '773', 'z' ) || ''; + $issn = $record->subfield( '773', 'x' ) || ''; + if ($mtx eq 'journal') { + $title .= "&rft.title=" . (($record->subfield( '773', 't' ) || $record->subfield( '773', 'a'))); + } else { + $title .= "&rft.btitle=" . (($record->subfield( '773', 't' ) || $record->subfield( '773', 'a')) || ''); + } + foreach my $rel ($record->subfield( '773', 'g' )) { + if ($pages) { + $pages .= ', '; + } + $pages .= $rel; + } + } else { + $pubyear = $record->subfield( '260', 'c' ) || ''; + $publisher = $record->subfield( '260', 'b' ) || ''; + $isbn = $record->subfield( '020', 'a' ) || ''; + $issn = $record->subfield( '022', 'a' ) || ''; + } } my $coins_value = -"ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3A$mtx$genre$title&rft.isbn=$isbn&rft.issn=$issn&rft.aulast=$aulast&rft.aufirst=$aufirst$oauthors&rft.pub=$publisher&rft.date=$pubyear"; +"ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3A$mtx$genre$title&rft.isbn=$isbn&rft.issn=$issn&rft.aulast=$aulast&rft.aufirst=$aufirst$oauthors&rft.pub=$publisher&rft.date=$pubyear&rft.pages=$pages"; $coins_value =~ s/(\ |&[^a])/\+/g; $coins_value =~ s/\"/\"\;/g; @@ -1214,6 +1249,72 @@ sub GetCOinSBiblio { return $coins_value; } + +=head2 GetMarcPrice + +return the prices in accordance with the Marc format. +=cut + +sub GetMarcPrice { + my ( $record, $marcflavour ) = @_; + my @listtags; + my $subfield; + + if ( $marcflavour eq "MARC21" ) { + @listtags = ('345', '020'); + $subfield="c"; + } elsif ( $marcflavour eq "UNIMARC" ) { + @listtags = ('345', '010'); + $subfield="d"; + } else { + return; + } + + for my $field ( $record->field(@listtags) ) { + for my $subfield_value ($field->subfield($subfield)){ + #check value + return $subfield_value if ($subfield_value); + } + } + return 0; # no price found +} + +=head2 GetMarcQuantity + +return the quantity of a book. Used in acquisition only, when importing a file an iso2709 from a bookseller +Warning : this is not really in the marc standard. In Unimarc, Electre (the most widely used bookseller) use the 969$a + +=cut + +sub GetMarcQuantity { + my ( $record, $marcflavour ) = @_; + my @listtags; + my $subfield; + + if ( $marcflavour eq "MARC21" ) { + return 0 + } elsif ( $marcflavour eq "UNIMARC" ) { + @listtags = ('969'); + $subfield="a"; + } else { + return; + } + + for my $field ( $record->field(@listtags) ) { + for my $subfield_value ($field->subfield($subfield)){ + #check value + if ($subfield_value) { + # in France, the cents separator is the , but sometimes, ppl use a . + # in this case, the price will be x100 when unformatted ! Replace the . by a , to get a proper price calculation + $subfield_value =~ s/\./,/ if C4::Context->preference("CurrencyFormat") eq "FR"; + return $subfield_value; + } + } + } + return 0; # no price found +} + + =head2 GetAuthorisedValueDesc my $subfieldvalue =get_authorised_value_desc( @@ -1297,10 +1398,10 @@ ISBNs stored in differents places depending on MARC flavour sub GetMarcISBN { my ( $record, $marcflavour ) = @_; my $scope; - if ( $marcflavour eq "MARC21" ) { - $scope = '020'; - } else { # assume unimarc if not marc21 + if ( $marcflavour eq "UNIMARC" ) { $scope = '010'; + } else { # assume marc21 if not unimarc + $scope = '020'; } my @marcisbns; my $isbn = ""; @@ -1337,10 +1438,10 @@ The note are stored in differents places depending on MARC flavour sub GetMarcNotes { my ( $record, $marcflavour ) = @_; my $scope; - if ( $marcflavour eq "MARC21" ) { - $scope = '5..'; - } else { # assume unimarc if not marc21 + if ( $marcflavour eq "UNIMARC" ) { $scope = '3..'; + } else { # assume marc21 if not unimarc + $scope = '5..'; } my @marcnotes; my $note = ""; @@ -1377,12 +1478,12 @@ The subjects are stored in differents places depending on MARC flavour sub GetMarcSubjects { my ( $record, $marcflavour ) = @_; my ( $mintag, $maxtag ); - if ( $marcflavour eq "MARC21" ) { - $mintag = "600"; - $maxtag = "699"; - } else { # assume unimarc if not marc21 + if ( $marcflavour eq "UNIMARC" ) { $mintag = "600"; $maxtag = "611"; + } else { # assume marc21 if not unimarc + $mintag = "600"; + $maxtag = "699"; } my @marcsubjects; @@ -1390,6 +1491,8 @@ sub GetMarcSubjects { my $subfield = ""; my $marcsubject; + my $subject_limit = C4::Context->preference("TraceCompleteSubfields") ? 'su,complete-subfield' : 'su'; + foreach my $field ( $record->field('6..') ) { next unless $field->tag() >= $mintag && $field->tag() <= $maxtag; my @subfields_loop; @@ -1410,15 +1513,21 @@ sub GetMarcSubjects { my $value = $subject_subfield->[1]; my $linkvalue = $value; $linkvalue =~ s/(\(|\))//g; - my $operator = " and " unless $counter == 0; + my $operator; + if ( $counter != 0 ) { + $operator = ' and '; + } if ( $code eq 9 ) { $found9 = 1; @link_loop = ( { 'limit' => 'an', link => "$linkvalue" } ); } if ( not $found9 ) { - push @link_loop, { 'limit' => 'su', link => $linkvalue, operator => $operator }; + push @link_loop, { 'limit' => $subject_limit, link => $linkvalue, operator => $operator }; + } + my $separator; + if ( $counter != 0 ) { + $separator = C4::Context->preference('authoritysep'); } - my $separator = C4::Context->preference("authoritysep") unless $counter == 0; # ignore $9 my @this_link_loop = @link_loop; @@ -1448,12 +1557,12 @@ sub GetMarcAuthors { # tagslib useful for UNIMARC author reponsabilities my $tagslib = &GetMarcStructure( 1, '' ); # FIXME : we don't have the framework available, we take the default framework. May be buggy on some setups, will be usually correct. - if ( $marcflavour eq "MARC21" ) { - $mintag = "700"; - $maxtag = "720"; - } elsif ( $marcflavour eq "UNIMARC" ) { # assume unimarc if not marc21 + if ( $marcflavour eq "UNIMARC" ) { $mintag = "700"; $maxtag = "712"; + } elsif ( $marcflavour eq "MARC21" || $marcflavour eq "NORMARC" ) { # assume marc21 or normarc if not unimarc + $mintag = "700"; + $maxtag = "720"; } else { return; } @@ -1476,7 +1585,10 @@ sub GetMarcAuthors { my $value = $authors_subfield->[1]; my $linkvalue = $value; $linkvalue =~ s/(\(|\))//g; - my $operator = " and " unless $count_auth == 0; + my $operator; + if ( $count_auth != 0 ) { + $operator = ' and '; + } # if we have an authority link, use that as the link, otherwise use standard searching if ($subfield9) { @@ -1492,8 +1604,17 @@ sub GetMarcAuthors { $value = GetAuthorisedValueDesc( $field->tag(), $authors_subfield->[0], $authors_subfield->[1], '', $tagslib ) if ( $marcflavour eq 'UNIMARC' and ( $authors_subfield->[0] =~ /4/ ) ); my @this_link_loop = @link_loop; - my $separator = C4::Context->preference("authoritysep") unless $count_auth == 0; - push @subfields_loop, { code => $subfieldcode, value => $value, link_loop => \@this_link_loop, separator => $separator } unless ( $authors_subfield->[0] eq '9' ); + my $separator; + if ( $count_auth != 0 ) { + $separator = C4::Context->preference('authoritysep'); + } + push @subfields_loop, + { code => $subfieldcode, + value => $value, + link_loop => \@this_link_loop, + separator => $separator + } + unless ( $authors_subfield->[0] eq '9' ); $count_auth++; } push @marcauthors, { MARCAUTHOR_SUBFIELDS_LOOP => \@subfields_loop }; @@ -1568,12 +1689,12 @@ The series are stored in differents places depending on MARC flavour sub GetMarcSeries { my ( $record, $marcflavour ) = @_; my ( $mintag, $maxtag ); - if ( $marcflavour eq "MARC21" ) { - $mintag = "440"; - $maxtag = "490"; - } else { # assume unimarc if not marc21 + if ( $marcflavour eq "UNIMARC" ) { $mintag = "600"; $maxtag = "619"; + } else { # assume marc21 if not unimarc + $mintag = "440"; + $maxtag = "490"; } my @marcseries; @@ -1604,13 +1725,27 @@ sub GetMarcSeries { my $value = $series_subfield->[1]; my $linkvalue = $value; $linkvalue =~ s/(\(|\))//g; - my $operator = " and " unless $counter == 0; - push @link_loop, { link => $linkvalue, operator => $operator }; - my $separator = C4::Context->preference("authoritysep") unless $counter == 0; + if ( $counter != 0 ) { + push @link_loop, { link => $linkvalue, operator => ' and ', }; + } else { + push @link_loop, { link => $linkvalue, operator => undef, }; + } + my $separator; + if ( $counter != 0 ) { + $separator = C4::Context->preference('authoritysep'); + } if ($volume_number) { push @subfields_loop, { volumenum => $value }; } else { - push @subfields_loop, { code => $code, value => $value, link_loop => \@link_loop, separator => $separator, volumenum => $volume_number }; + if ( $series_subfield->[0] ne '9' ) { + push @subfields_loop, { + code => $code, + value => $value, + link_loop => \@link_loop, + separator => $separator, + volumenum => $volume_number, + }; + } } $counter++; } @@ -2226,8 +2361,11 @@ sub PrepareItemrecordDisplay { my $tagslib = &GetMarcStructure( 1, $frameworkcode ); # return nothing if we don't have found an existing framework. - return "" unless $tagslib; - my $itemrecord = C4::Items::GetMarcItem( $bibnum, $itemnum ) if ($itemnum); + return q{} unless $tagslib; + my $itemrecord; + if ($itemnum) { + $itemrecord = C4::Items::GetMarcItem( $bibnum, $itemnum ); + } my @loop_data; my $authorised_values_sth = $dbh->prepare( "SELECT authorised_value,lib FROM authorised_values WHERE category=? ORDER BY lib" ); foreach my $tag ( sort keys %{$tagslib} ) { @@ -2266,15 +2404,20 @@ sub PrepareItemrecordDisplay { && C4::Context->preference('itemcallnumber') ) { my $CNtag = substr( C4::Context->preference('itemcallnumber'), 0, 3 ); my $CNsubfield = substr( C4::Context->preference('itemcallnumber'), 3, 1 ); - my $temp = $itemrecord->field($CNtag) if ($itemrecord); - if ($temp) { - $defaultvalue = $temp->subfield($CNsubfield); + if ($itemrecord) { + my $temp = $itemrecord->field($CNtag); + if ($temp) { + $defaultvalue = $temp->subfield($CNsubfield); + } } } if ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.itemcallnumber' && $defaultvalues && $defaultvalues->{'callnumber'} ) { - my $temp = $itemrecord->field($subfield) if ($itemrecord); + my $temp; + if ($itemrecord) { + $temp = $itemrecord->field($subfield); + } unless ($temp) { $defaultvalue = $defaultvalues->{'callnumber'} if $defaultvalues; } @@ -2282,11 +2425,22 @@ sub PrepareItemrecordDisplay { if ( ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.holdingbranch' || $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.homebranch' ) && $defaultvalues && $defaultvalues->{'branchcode'} ) { - my $temp = $itemrecord->field($subfield) if ($itemrecord); + my $temp; + if ($itemrecord) { + $temp = $itemrecord->field($subfield); + } unless ($temp) { $defaultvalue = $defaultvalues->{branchcode} if $defaultvalues; } } + if ( ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.location' ) + && $defaultvalues + && $defaultvalues->{'location'} ) { + my $temp = $itemrecord->field($subfield) if ($itemrecord); + unless ($temp) { + $defaultvalue = $defaultvalues->{location} if $defaultvalues; + } + } if ( $tagslib->{$tag}->{$subfield}->{authorised_value} ) { my @authorised_values; my %authorised_lib; @@ -2358,6 +2512,40 @@ sub PrepareItemrecordDisplay { -tabindex => '', -multiple => 0, ); + } elsif ( $tagslib->{$tag}->{$subfield}->{value_builder} ) { + # opening plugin + my $plugin = C4::Context->intranetdir . "/cataloguing/value_builder/" . $tagslib->{$tag}->{$subfield}->{'value_builder'}; + if (do $plugin) { + my $temp; + my $extended_param = plugin_parameters( $dbh, $temp, $tagslib, $subfield_data{id}, undef ); + my ( $function_name, $javascript ) = plugin_javascript( $dbh, $temp, $tagslib, $subfield_data{id}, undef ); + $subfield_data{random} = int(rand(1000000)); # why do we need 2 different randoms? + my $index_subfield = int(rand(1000000)); + $subfield_data{id} = "tag_".$tag."_subfield_".$subfield."_".$index_subfield; + $subfield_data{marc_value} = qq[ + ... + $javascript]; + } else { + warn "Plugin Failed: $plugin"; + $subfield_data{marc_value} = qq(); # supply default input form + } + } + elsif ( $tag eq '' ) { # it's an hidden field + $subfield_data{marc_value} = qq(); + } + elsif ( $tagslib->{$tag}->{$subfield}->{'hidden'} ) { # FIXME: shouldn't input type be "hidden" ? + $subfield_data{marc_value} = qq(); + } + elsif ( length($defaultvalue) > 100 + or (C4::Context->preference("marcflavour") eq "UNIMARC" and + 300 <= $tag && $tag < 400 && $subfield eq 'a' ) + or (C4::Context->preference("marcflavour") eq "MARC21" and + 500 <= $tag && $tag < 600 ) + ) { + # oversize field (textarea) + $subfield_data{marc_value} = qq(\n"); } else { $subfield_data{marc_value} = ""; } @@ -2365,8 +2553,10 @@ sub PrepareItemrecordDisplay { } } } - my $itemnumber = $itemrecord->subfield( $itemtagfield, $itemtagsubfield ) - if ( $itemrecord && $itemrecord->field($itemtagfield) ); + my $itemnumber; + if ( $itemrecord && $itemrecord->field($itemtagfield) ) { + $itemnumber = $itemrecord->subfield( $itemtagfield, $itemtagsubfield ); + } return { 'itemtagfield' => $itemtagfield, 'itemtagsubfield' => $itemtagsubfield, @@ -2513,6 +2703,36 @@ sub GetNoZebraIndexes { return %indexes; } +=head2 EmbedItemsInMarcBiblio + + EmbedItemsInMarcBiblio($marc, $biblionumber); + +Given a MARC::Record object containing a bib record, +modify it to include the items attached to it as 9XX +per the bib's MARC framework. + +=cut + +sub EmbedItemsInMarcBiblio { + my ($marc, $biblionumber) = @_; + croak "No MARC record" unless $marc; + + my $frameworkcode = GetFrameworkCode($biblionumber); + _strip_item_fields($marc, $frameworkcode); + + # ... and embed the current items + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare("SELECT itemnumber FROM items WHERE biblionumber = ?"); + $sth->execute($biblionumber); + my @item_fields; + my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField( "items.itemnumber", $frameworkcode ); + while (my ($itemnumber) = $sth->fetchrow_array) { + my $item_marc = C4::Items::GetMarcItem($biblionumber, $itemnumber); + push @item_fields, $item_marc->field($itemtag); + } + $marc->insert_fields_ordered(@item_fields); +} + =head1 INTERNAL FUNCTIONS =head2 _DelBiblioNoZebra($biblionumber,$record,$server); @@ -2851,7 +3071,7 @@ sub _koha_marc_update_bib_ids { # drop old field and create new one... $old_field = $record->field($biblio_tag); $record->delete_field($old_field) if $old_field; - $record->append_fields($new_field); + $record->insert_fields_ordered($new_field); # deal with biblioitemnumber if ( $biblioitem_tag < 10 ) { @@ -3267,7 +3487,7 @@ sub ModBiblioMarc { } substr( $string, 22, 6, "frey50" ); unless ( $record->subfield( 100, "a" ) ) { - $record->insert_grouped_field( MARC::Field->new( 100, "", "", "a" => $string ) ); + $record->insert_fields_ordered( MARC::Field->new( 100, "", "", "a" => $string ) ); } }