(Bug 4049) Searching itemtypes returning noise
[koha_fer] / C4 / Biblio.pm
index 879dd0a..a0e06f6 100644 (file)
@@ -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/\"/\&quot\;/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 "MARC21" ) {
+        $scope = '020';
+    } else {    # assume unimarc if not marc21
+        $scope = '010';
+    }
+    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 );
@@ -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;
 
@@ -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;