package C4::Biblio;
# Copyright 2000-2002 Katipo Communications
+# Copyright 2010 BibLibre
#
# This file is part of Koha.
#
&GetMarcControlnumber
&GetMarcNotes
+ &GetMarcISBN
&GetMarcSubjects
&GetMarcBiblio
&GetMarcAuthors
&GetMarcStructure
&GetMarcFromKohaField
&GetFrameworkCode
- &GetPublisherNameFromIsbn
&TransformKohaToMarc
&CountItemsIssued
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;
logaction( "CATALOGUING", "MODIFY", $biblionumber, "BEFORE=>" . $newrecord->as_formatted );
}
+ SetUTF8Flag($record);
my $dbh = C4::Context->dbh;
$frameworkcode = "" unless $frameworkcode;
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
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;
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' );
} else {
# MARC21 need some improve
- my $fmts;
- $mtx = 'book';
- $genre = "&rft.genre=book";
# Setting datas
if ( $record->field('100') ) {
$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;
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 );
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 = "";
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;
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;
@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;
# 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;
}
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;
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++;
}
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 )
}
$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;
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 ] ), );
$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;
-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[<input tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255"
+ onfocus="Focus$function_name($subfield_data{random}, '$subfield_data{id}');"
+ onblur=" Blur$function_name($subfield_data{random}, '$subfield_data{id}');" />
+ <a href="#" class="buttonDot" onclick="Clic$function_name('$subfield_data{id}'); return false;" title="Tag Editor">...</a>
+ $javascript];
+ } else {
+ warn "Plugin Failed: $plugin";
+ $subfield_data{marc_value} = qq(<input tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255" />); # supply default input form
+ }
+ }
+ elsif ( $tag eq '' ) { # it's an hidden field
+ $subfield_data{marc_value} = qq(<input type="hidden" tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255" value="$defaultvalue" />);
+ }
+ elsif ( $tagslib->{$tag}->{$subfield}->{'hidden'} ) { # FIXME: shouldn't input type be "hidden" ?
+ $subfield_data{marc_value} = qq(<input type="text" tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255" value="$defaultvalue" />);
+ }
+ 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(<textarea tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255">$defaultvalue</textarea>\n");
} else {
$subfield_data{marc_value} = "<input type=\"text\" name=\"field_value\" value=\"$defaultvalue\" size=\"50\" maxlength=\"255\" />";
}
$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") ) {