X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=C4%2FBiblio.pm;h=7b72411c575b4fefcdb8f628da5fe8bba8b5afc2;hb=40b49900c34e47916ebf7c8ec4a73446dec72820;hp=c3a30946db342e063b810f2141d5a20b9ee8013c;hpb=f90f92f80f54b658843281bd7eb013cc87786ce9;p=koha_gimpoz diff --git a/C4/Biblio.pm b/C4/Biblio.pm old mode 100644 new mode 100755 index c3a30946db..7b72411c57 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -1,6 +1,7 @@ package C4::Biblio; # Copyright 2000-2002 Katipo Communications +# Copyright 2010 BibLibre # # This file is part of Koha. # @@ -69,6 +70,7 @@ BEGIN { &GetMarcControlnumber &GetMarcNotes + &GetMarcISBN &GetMarcSubjects &GetMarcBiblio &GetMarcAuthors @@ -82,7 +84,6 @@ BEGIN { &GetMarcStructure &GetMarcFromKohaField &GetFrameworkCode - &GetPublisherNameFromIsbn &TransformKohaToMarc &CountItemsIssued @@ -249,6 +250,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; @@ -293,6 +295,7 @@ sub ModBiblio { logaction( "CATALOGUING", "MODIFY", $biblionumber, "BEFORE=>" . $newrecord->as_formatted ); } + SetUTF8Flag($record); my $dbh = C4::Context->dbh; $frameworkcode = "" unless $frameworkcode; @@ -317,15 +320,28 @@ sub ModBiblio { foreach my $fielditem (@fields) { my $field; foreach ( $fielditem->subfields() ) { + # re-encode the subfield only if it isn't already in utf-8. + my ($tag, $value) = @$_; + $tag = Encode::encode('utf-8', $tag) unless utf8::is_utf8($tag); + $value = Encode::encode('utf-8', $value) unless utf8::is_utf8($value); + if ($field) { - $field->add_subfields( Encode::encode( 'utf-8', $_->[0] ) => Encode::encode( 'utf-8', $_->[1] ) ); + $field->add_subfields( $tag => $value ); } else { - $field = MARC::Field->new( "$itemtag", '', '', Encode::encode( 'utf-8', $_->[0] ) => Encode::encode( 'utf-8', $_->[1] ) ); + $field = MARC::Field->new( "$itemtag", '', '', $tag => $value ); } } $record->append_fields($field); } + foreach my $field ($record->fields()) { + if (! $field->is_control_field()) { + if (scalar($field->subfields()) == 0) { + $record->delete_fields($field); + } + } + } + # update biblionumber and biblioitemnumber in MARC # FIXME - this is assuming a 1 to 1 relationship between # biblios and biblioitems @@ -747,7 +763,7 @@ sub GetISBDView { 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; @@ -1105,50 +1121,57 @@ 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' ); @@ -1172,9 +1195,6 @@ sub GetCOinSBiblio { } else { # MARC21 need some improve - my $fmts; - $mtx = 'book'; - $genre = "&rft.genre=book"; # Setting datas if ( $record->field('100') ) { @@ -1187,17 +1207,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; @@ -1277,6 +1314,46 @@ sub GetMarcControlnumber { return $controlnumber; } +=head2 GetMarcISBN + + $marcisbnsarray = GetMarcISBN( $record, $marcflavour ); + +Get all ISBNs from the MARC record and returns them in an array. +ISBNs stored in differents places depending on MARC flavour + +=cut + +sub GetMarcISBN { + my ( $record, $marcflavour ) = @_; + my $scope; + if ( $marcflavour eq "UNIMARC" ) { + $scope = '010'; + } else { # assume marc21 if not unimarc + $scope = '020'; + } + my @marcisbns; + my $isbn = ""; + my $tag = ""; + my $marcisbn; + foreach my $field ( $record->field($scope) ) { + my $value = $field->as_string(); + if ( $isbn ne "" ) { + $marcisbn = { marcisbn => $isbn, }; + push @marcisbns, $marcisbn; + $isbn = $value; + } + if ( $isbn ne $value ) { + $isbn = $isbn . " " . $value; + } + } + + if ($isbn) { + $marcisbn = { marcisbn => $isbn }; + push @marcisbns, $marcisbn; #load last tag into array + } + return \@marcisbns; +} # end GetMarcISBN + =head2 GetMarcNotes $marcnotesarray = GetMarcNotes( $record, $marcflavour ); @@ -1289,10 +1366,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 = ""; @@ -1329,12 +1406,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; @@ -1342,6 +1419,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; @@ -1368,7 +1447,7 @@ sub GetMarcSubjects { @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 = C4::Context->preference("authoritysep") unless $counter == 0; @@ -1400,12 +1479,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; } @@ -1520,12 +1599,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; @@ -1562,7 +1641,7 @@ sub GetMarcSeries { 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 }; + push @subfields_loop, { code => $code, value => $value, link_loop => \@link_loop, separator => $separator, volumenum => $volume_number } unless ( $series_subfield->[0] eq '9' ); } $counter++; } @@ -1592,36 +1671,6 @@ sub GetFrameworkCode { return $frameworkcode; } -=head2 GetPublisherNameFromIsbn - - $name = GetPublishercodeFromIsbn($isbn); - if(defined $name){ - ... - } - -=cut - -sub GetPublisherNameFromIsbn($) { - my $isbn = shift; - $isbn =~ s/[- _]//g; - $isbn =~ s/^0*//; - my @codes = ( split '-', DisplayISBN($isbn) ); - my $code = $codes[0] . $codes[1] . $codes[2]; - my $dbh = C4::Context->dbh; - my $query = qq{ - SELECT distinct publishercode - FROM biblioitems - WHERE isbn LIKE ? - AND publishercode IS NOT NULL - LIMIT 1 - }; - my $sth = $dbh->prepare($query); - $sth->execute("$code%"); - my $name = $sth->fetchrow; - return $name if length $name; - return undef; -} - =head2 TransformKohaToMarc $record = TransformKohaToMarc( $hash ) @@ -1662,13 +1711,18 @@ sub TransformKohaToMarcOneField { } $sth->execute( $frameworkcode, $kohafieldname ); if ( ( $tagfield, $tagsubfield ) = $sth->fetchrow ) { + my @values = split(/\s?\|\s?/, $value, -1); + + foreach my $itemvalue (@values){ my $tag = $record->field($tagfield); if ($tag) { - $tag->update( $tagsubfield => $value ); + $tag->add_subfields( $tagsubfield => $itemvalue ); $record->delete_field($tag); $record->insert_fields_ordered($tag); - } else { - $record->add_fields( $tagfield, " ", " ", $tagsubfield => $value ); + } + else { + $record->add_fields( $tagfield, " ", " ", $tagsubfield => $itemvalue ); + } } } return $record; @@ -1901,8 +1955,14 @@ sub TransformHtmlToMarc { if ( $tag < 10 ) { # no code for theses fields # in MARC editor, 000 contains the leader. if ( $tag eq '000' ) { - $record->leader( $cgi->param( $params->[ $j + 1 ] ) ) if length( $cgi->param( $params->[ $j + 1 ] ) ) == 24; - + # Force a fake leader even if not provided to avoid crashing + # during decoding MARC record containing UTF-8 characters + $record->leader( + length( $cgi->param($params->[$j+1]) ) == 24 + ? $cgi->param( $params->[ $j + 1 ] ) + : ' nam a22 4500' + ) + ; # between 001 and 009 (included) } elsif ( $cgi->param( $params->[ $j + 1 ] ) ne '' ) { $newfield = MARC::Field->new( $tag, $cgi->param( $params->[ $j + 1 ] ), ); @@ -2258,6 +2318,14 @@ sub PrepareItemrecordDisplay { $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; @@ -2329,6 +2397,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} = ""; } @@ -3241,6 +3343,15 @@ sub ModBiblioMarc { $record->insert_grouped_field( MARC::Field->new( 100, "", "", "a" => $string ) ); } } + + #enhancement 5374: update transaction date (005) for marc21/unimarc + if($encoding =~ /MARC21|UNIMARC/) { + my @a= (localtime) [5,4,3,2,1,0]; $a[0]+=1900; $a[1]++; + # YY MM DD HH MM SS (update year and month) + my $f005= $record->field('005'); + $f005->update(sprintf("%4d%02d%02d%02d%02d%04.1f",@a)) if $f005; + } + my $oldRecord; if ( C4::Context->preference("NoZebra") ) {