(bug #3734) Fix previous patch of isbd view
[koha.git] / C4 / Biblio.pm
index 8fa1389..6599c33 100755 (executable)
@@ -36,7 +36,7 @@ use C4::Charset;
 require C4::Heading;
 require C4::Serials;
 
-use vars qw($VERSION @ISA @EXPORT);
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
 
 BEGIN {
        $VERSION = 1.00;
@@ -46,6 +46,10 @@ BEGIN {
 
        # to add biblios
 # EXPORTED FUNCTIONS.
+    push @EXPORT_OK, qw(
+        &GetRecordValue
+    );
+
        push @EXPORT, qw( 
                &AddBiblio
        );
@@ -58,6 +62,12 @@ BEGIN {
                &GetBiblioItemInfosOf
                &GetBiblioItemByBiblioNumber
                &GetBiblioFromItemNumber
+               &GetBiblioSummary
+               
+               &GetRecordValue
+               &GetFieldMapping
+               &SetFieldMapping
+               &DeleteFieldMapping
                
                &GetISBDView
 
@@ -466,6 +476,115 @@ sub LinkBibHeadingsToAuthorities {
     return $num_headings_changed;
 }
 
+=head2 GetRecordValue
+
+=over 4
+
+my $values = GetRecordValue($field, $record, $frameworkcode);
+
+=back
+
+Get MARC fields from a keyword defined in fieldmapping table.
+
+=cut
+
+sub GetRecordValue {
+    my ($field, $record, $frameworkcode) = @_;
+    my $dbh = C4::Context->dbh;
+    
+    my $sth = $dbh->prepare('SELECT fieldcode, subfieldcode FROM fieldmapping WHERE frameworkcode = ? AND field = ?');
+    $sth->execute($frameworkcode, $field);
+    
+    my @result = ();
+    
+    while(my $row = $sth->fetchrow_hashref){
+        foreach my $field ($record->field($row->{fieldcode})){
+            if( ($row->{subfieldcode} ne "" && $field->subfield($row->{subfieldcode}))){
+                foreach my $subfield ($field->subfield($row->{subfieldcode})){
+                    push @result, { 'subfield' => $subfield };
+                }
+                
+            }elsif($row->{subfieldcode} eq "") {
+                push @result, {'subfield' => $field->as_string()};
+            }
+        }
+    }
+    
+    return \@result;
+}
+
+=head2 SetFieldMapping
+
+=over 4
+
+SetFieldMapping($framework, $field, $fieldcode, $subfieldcode);
+
+=back
+
+Set a Field to MARC mapping value, if it already exists we don't add a new one.
+
+=cut
+
+sub SetFieldMapping {
+    my ($framework, $field, $fieldcode, $subfieldcode) = @_;
+    my $dbh = C4::Context->dbh;
+    
+    my $sth = $dbh->prepare('SELECT * FROM fieldmapping WHERE fieldcode = ? AND subfieldcode = ? AND frameworkcode = ? AND field = ?');
+    $sth->execute($fieldcode, $subfieldcode, $framework, $field);
+    if(not $sth->fetchrow_hashref){
+        my @args;
+        $sth = $dbh->prepare('INSERT INTO fieldmapping (fieldcode, subfieldcode, frameworkcode, field) VALUES(?,?,?,?)');
+        
+        $sth->execute($fieldcode, $subfieldcode, $framework, $field);
+    }
+}
+
+=head2 DeleteFieldMapping
+
+=over 4
+
+DeleteFieldMapping($id);
+
+=back
+
+Delete a field mapping from an $id.
+
+=cut
+
+sub DeleteFieldMapping{
+    my ($id) = @_;
+    my $dbh = C4::Context->dbh;
+    
+    my $sth = $dbh->prepare('DELETE FROM fieldmapping WHERE id = ?');
+    $sth->execute($id);
+}
+
+=head2 GetFieldMapping
+
+=over 4
+
+GetFieldMapping($frameworkcode);
+
+=back
+
+Get all field mappings for a specified frameworkcode
+
+=cut
+
+sub GetFieldMapping {
+    my ($framework) = @_;
+    my $dbh = C4::Context->dbh;
+    
+    my $sth = $dbh->prepare('SELECT * FROM fieldmapping where frameworkcode = ?');
+    $sth->execute($framework);
+    
+    my @return;
+    while(my $row = $sth->fetchrow_hashref){
+        push @return, $row;
+    }
+    return \@return;
+}
+
 =head2 GetBiblioData
 
 =over 4
@@ -624,13 +743,17 @@ Return the ISBD view which can be included in opac and intranet
 =cut
 
 sub GetISBDView {
-    my $biblionumber    = shift;
+    my ($biblionumber, $template) = @_;
     my $record          = GetMarcBiblio($biblionumber);
     my $itemtype        = &GetFrameworkCode($biblionumber);
     my ($holdingbrtagf,$holdingbrtagsubf) = &GetMarcFromKohaField("items.holdingbranch",$itemtype);
     my $tagslib      = &GetMarcStructure( 1, $itemtype );
     
     my $ISBD = C4::Context->preference('ISBD');
+    if($template eq "opac"){
+        $ISBD = C4::Context->preference('OPACISBD');
+    }
+    
     my $bloc = $ISBD;
     my $res;
     my $blocres;
@@ -668,7 +791,6 @@ sub GetISBDView {
                     my $tagsubf = $tag . $subfvalue;
                     $calculated =~
                           s/\{(.?.?.?.?)$tagsubf(.*?)\}/$1$subfieldvalue$2\{$1$tagsubf$2\}/g;
-                    $calculated =~s#/cgi-bin/koha/[^/]+/([^.]*.pl\?.*)$#opac-$1#g;
                 
                     # field builded, store the result
                     if ( $calculated && !$hasputtextbefore )
@@ -694,22 +816,16 @@ sub GetISBDView {
               else {
                 my @subf = $field->subfields;
                 for my $i ( 0 .. $#subf ) {
-                my $valuecode   = $subf[$i][1];
-                my $subfieldcode  = $subf[$i][0];
-                my $subfieldvalue =
-                GetAuthorisedValueDesc( $tag, $subf[$i][0],
-                  $subf[$i][1], '', $tagslib );
-                my $tagsubf = $tag . $subfieldcode;
-    
-                $calculated =~ s/                  # replace all {{}} codes by the value code.
-                                  \{\{$tagsubf\}\} # catch the {{actualcode}}
-                                /
-                                  $valuecode     # replace by the value code
-                               /gx;
-    
-                $calculated =~
-            s/\{(.?.?.?.?)$tagsubf(.*?)\}/$1$subfieldvalue$2\{$1$tagsubf$2\}/g;
-            $calculated =~s#/cgi-bin/koha/[^/]+/([^.]*.pl\?.*)$#opac-$1#g;
+                    my $valuecode   = $subf[$i][1];
+                    my $subfieldcode  = $subf[$i][0];
+                    my $subfieldvalue =
+                    GetAuthorisedValueDesc( $tag, $subf[$i][0],
+                      $subf[$i][1], '', $tagslib );
+                    my $tagsubf = $tag . $subfieldcode;
+        
+                    $calculated =~ s/\{\{$tagsubf\}\}/$valuecode/gx;
+                    $calculated =~
+                        s/\{(.?.?.?.?)$tagsubf(.*?)\}/$1$subfieldvalue$2\{$1$tagsubf$2\}/g;
                 }
     
                 # field builded, store the result
@@ -1081,8 +1197,8 @@ sub GetCOinSBiblio {
         $genre = ($mtx eq 'dc') ? "&rft.type=$genre" : "&rft.genre=$genre";
 
         # 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
         if($record->field('200')){
@@ -1092,10 +1208,10 @@ sub GetCOinSBiblio {
         }
         $title      = ( $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;
@@ -1128,6 +1244,119 @@ sub GetCOinSBiblio {
     return $coins_value;
 }
 
+=head2 GetBiblioSummary
+
+=over 4
+
+$summary = GetBiblioSummary($marcrecord);
+
+Return the summary of a record.
+
+=back
+
+=cut
+
+sub GetBiblioSummary {
+    my $recorddata =shift @_;
+    
+    my $marcflavour = C4::Context->preference("marcflavour");
+    my $marc=MARC::Record::new_from_xml($recorddata,"utf-8",$marcflavour);
+    
+    my $str;
+    
+    if($marcflavour eq "MARC21"){
+        $str="<b>".$marc->subfield('245',"a")."</b>" if $marc->subfield('245','a');
+        $str.= " <i>".$marc->subfield('245',"b")."</i> " if $marc->subfield('245','b');
+        
+        if ($marc->field('245')){
+            $str.=" / ";
+            foreach ($marc->field('100')->subfield("a")) {
+                $str.=$_." ; ";
+            }
+            $str=~s/ ; $/. /; 
+        }
+      
+        if ($marc->field('260')){
+            $str.=" - ";
+            $str.=$marc->subfield('260',"a")." " if $marc->subfield('260','a');
+            $str.=" : ".$marc->subfield('260',"b")." " if $marc->subfield('260','b');
+            $str.=", ".$marc->subfield('260',"c")." " if $marc->subfield('260','c');
+        }
+        if ($marc->field('300')){
+            $str.=" - ";
+            $str.=$marc->subfield('300','a') if ($marc->subfield(300,'a'));
+            $str.=" ; ".$marc->subfield('300','b') if $marc->subfield('300','b');
+            $str.=" ; ".$marc->subfield('300','c') if $marc->subfield('300','c');
+            $str.=" ; ".$marc->subfield('300','e') if $marc->subfield('300','e');
+        }
+        foreach ($marc->field('500')){
+            $str.= " - ";
+            foreach ($_->subfield("a")){
+                $str.=$_."; "
+            } 
+        }
+        my $itemtypes=GetItemTypes();
+        $str.=" - <u>".$itemtypes->{$marc->subfield('942','c')}->{'description'}."</u> ";
+        $str.="<br />\n";
+       
+    }else{
+        $str = "<b>".$marc->subfield('200','a')."</b>"   if $marc->subfield('200','a');
+        $str.= " <i>".$marc->subfield('200','e')."</i> " if $marc->subfield('200','e');
+        if ($marc->field('200')){
+            $str.=" / ";
+            foreach ($marc->field('200')->subfield("f")) {
+                $str.=$_." ; ";
+            }
+            $str=~s/ ; $/. /; 
+        }
+        
+        if ($marc->subfield('200','g')){
+            $str.=" ; ";
+            foreach ($marc->field('200')->subfield("g")){
+                $str.=$_." ; ";
+            } 
+            $str=~s/ ; $/. /; 
+        }
+        
+        if ($marc->field('461')){
+            $str.="- In :";
+            $str.=     $marc->subfield('461','t') if $marc->subfield('461','t');
+            $str.=", ".$marc->subfield('461','d') if $marc->subfield('461','d');
+            $str.=", ".$marc->subfield('461','v') if $marc->subfield('461','v');
+            $str.=", ".$marc->subfield('461','h') if $marc->subfield('461','h');
+            $str.=" ; ".$marc->subfield('461','x') if $marc->subfield('461','x');
+        }
+        
+        if ($marc->field('210')){
+            $str.=" - ";
+            $str.=$marc->subfield('210',"a")." " if $marc->subfield('210','a');
+            $str.=" : ".$marc->subfield('210',"c")." " if $marc->subfield('210','c');
+            $str.=", ".$marc->subfield('210',"d")." " if $marc->subfield('210','d');
+        }
+        
+        if ($marc->field('215')){
+            $str.=" - ";
+            $str.=$marc->subfield('215','a') if ($marc->subfield(215,'a'));
+            $str.=" ; ".$marc->subfield('215','d') if $marc->subfield('215','d');
+            $str.=" ; ".$marc->subfield('215','c') if $marc->subfield('215','c');
+            $str.=" ; ".$marc->subfield('215','e') if $marc->subfield('215','e');
+        }
+        foreach ($marc->field('300')){
+            $str.=" - ";
+            foreach ($_->subfield("a")){
+                $str.=$_."; "
+            } 
+        }
+        
+        my $itemtypes=GetItemTypes;
+        if($itemtypes->{$marc->subfield('200','b')}){
+            $str.=" - <u>".$itemtypes->{$marc->subfield('200','b')}->{'description'}."</u> ";
+        }
+        $str.="<br />\n";         
+    }    
+    return $str;
+}
+
 =head2 GetAuthorisedValueDesc
 
 =over 4
@@ -1647,20 +1876,22 @@ sub TransformHtmlToXml {
 #         }
         if ( ( @$tags[$i] ne $prevtag ) ) {
             $j++ unless ( @$tags[$i] eq "" );
+                       my $indicator1=eval{substr( @$indicator[$j], 0, 1 )};
+                       my $indicator2=eval{substr( @$indicator[$j], 1, 1 )};
+            my $ind1 = _default_ind_to_space($indicator1);
+            my $ind2;
+            if ( @$indicator[$j] ) {
+               $ind2 = _default_ind_to_space($indicator2);
+            }
+            else {
+               warn "Indicator in @$tags[$i] is empty";
+               $ind2 = " ";
+            }
             if ( !$first ) {
                 $xml .= "</datafield>\n";
                 if (   ( @$tags[$i] && @$tags[$i] > 10 )
                     && ( @$values[$i] ne "" ) )
                 {
-                    my $ind1 = substr( @$indicator[$j], 0, 1 );
-                    my $ind2;
-                    if ( @$indicator[$j] ) {
-                        $ind2 = substr( @$indicator[$j], 1, 1 );
-                    }
-                    else {
-                        warn "Indicator in @$tags[$i] is empty";
-                        $ind2 = " ";
-                    }
                     $xml .= "<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
                     $xml .= "<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
                     $first = 0;
@@ -1684,10 +1915,6 @@ sub TransformHtmlToXml {
                         $first = 1;
                     }
                     else {
-                        my $ind1 = substr( @$indicator[$j], 0, 1 );
-                        my $ind2 = substr( @$indicator[$j], 1, 1 );
-                        $ind1 = " " if !defined($ind2) or $ind2 eq "";
-                        $ind2 = " " if !defined($ind2) or $ind2 eq "";
                         $xml .= "<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
                         $xml .= "<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
                         $first = 0;
@@ -1696,14 +1923,21 @@ sub TransformHtmlToXml {
             }
         }
         else {    # @$tags[$i] eq $prevtag
-            if ( @$values[$i] eq "" ) {
+                       my $indicator1=eval{substr( @$indicator[$j], 0, 1 )};
+                       my $indicator2=eval{substr( @$indicator[$j], 1, 1 )};
+            my $ind1 = _default_ind_to_space($indicator1);
+            my $ind2;
+            if ( @$indicator[$j] ) {
+               $ind2 = _default_ind_to_space($indicator2);
+            }
+            else {
+               warn "Indicator in @$tags[$i] is empty";
+               $ind2 = " ";
+            }
+         if ( @$values[$i] eq "" ) {
             }
             else {
                 if ($first) {
-                    my $ind1 = substr( @$indicator[$j], 0, 1 );
-                    my $ind2 = substr( @$indicator[$j], 1, 1 );
-                    $ind1 = " " if !defined($ind2) or $ind2 eq "";
-                    $ind2 = " " if !defined($ind2) or $ind2 eq "";
                     $xml .= "<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
                     $first = 0;
                 }
@@ -1730,6 +1964,21 @@ sub TransformHtmlToXml {
     return $xml;
 }
 
+=head2 _default_ind_to_space
+
+Passed what should be an indicator returns a space
+if its undefined or zero length
+
+=cut
+
+sub _default_ind_to_space {
+    my $s = shift;
+    if (!defined $s || $s eq q{}) {
+        return ' ';
+    }
+    return $s;
+}
+
 =head2 TransformHtmlToMarc
 
     L<$record> = TransformHtmlToMarc(L<$params>,L<$cgi>)
@@ -1802,8 +2051,8 @@ sub TransformHtmlToMarc {
         elsif ($param =~ /^tag_(\d*)_indicator1_/){ # new field start when having 'input name="..._indicator1_..."
             my $tag  = $1;
             
-            my $ind1 = substr($cgi->param($param),0,1);
-            my $ind2 = substr($cgi->param($params->[$i+1]),0,1);
+            my $ind1 = _default_ind_to_space(substr($cgi->param($param),          0, 1));
+            my $ind2 = _default_ind_to_space(substr($cgi->param($params->[$i+1]), 0, 1));
             $newfield=0;
             my $j=$i+2;
             
@@ -1832,8 +2081,8 @@ sub TransformHtmlToMarc {
                         if ( $cgi->param($params->[$j+1]) ne '' ) { # creating only if there is a value (code => value)
                             $newfield = MARC::Field->new(
                                 $tag,
-                                ''.$ind1,
-                                ''.$ind2,
+                                $ind1,
+                                $ind2,
                                 $cgi->param($inner_param) => $cgi->param($params->[$j+1]),
                             );
                         }
@@ -2139,11 +2388,15 @@ sub PrepareItemrecordDisplay {
     my ( $bibnum, $itemnum, $defaultvalues ) = @_;
 
     my $dbh = C4::Context->dbh;
+       my $today_iso = C4::Dates->today('iso');
     my $frameworkcode = &GetFrameworkCode( $bibnum );
     my ( $itemtagfield, $itemtagsubfield ) =
       &GetMarcFromKohaField( "items.itemnumber", $frameworkcode );
     my $tagslib = &GetMarcStructure( 1, $frameworkcode );
     my $itemrecord = C4::Items::GetMarcItem( $bibnum, $itemnum) if ($itemnum);
+       # FIXME : I'd rather have GetMarcBiblio called out of this.
+       # Since it gets the whole Biblio record for each item
+    my $marcrecord = GetMarcBiblio( $bibnum) if ($bibnum);
     my @loop_data;
     my $authorised_values_sth =
       $dbh->prepare(
@@ -2176,9 +2429,15 @@ sub PrepareItemrecordDisplay {
                   if ($itemrecord) {
                       ( $x, $value ) = _find_value( $tag, $subfield, $itemrecord );
                   }
-                  if (!defined $value) {
-                      $value = q||;
-                  }
+                                 unless ($value) {
+                                               $value   = $tagslib->{$tag}->{$subfield}->{defaultvalue};
+                                               $value ||= $defaultvalues->{$tagslib->{$tag}->{$subfield}->{'kohafield'}};
+                                               # get today date & replace YYYY, MM, DD if provided in the default value
+                                               my ( $year, $month, $day ) = split ',', $today_iso;     # FIXME: iso dates don't have commas!
+                                               $value =~ s/YYYY/$year/g;
+                                               $value =~ s/MM/$month/g;
+                                               $value =~ s/DD/$day/g;
+                                 }
                   $value =~ s/"/&quot;/g;
 
                 # search for itemcallnumber if applicable
@@ -2190,7 +2449,7 @@ sub PrepareItemrecordDisplay {
                       substr( C4::Context->preference('itemcallnumber'), 0, 3 );
                     my $CNsubfield =
                       substr( C4::Context->preference('itemcallnumber'), 3, 1 );
-                    my $temp = $itemrecord->field($CNtag) if ($itemrecord);
+                    my $temp = $marcrecord->field($CNtag) if ($marcrecord);
                     if ($temp) {
                         $value = $temp->subfield($CNsubfield);
                     }
@@ -2646,7 +2905,8 @@ sub _AddBiblioNoZebra {
                 foreach (split / /,$line) {
                     next unless $_; # skip  empty values (multiple spaces)
                     # if the entry is already here, improve weight
-                    if ($result{'__RAW__'}->{"$_"} =~ /$biblionumber,\Q$title\E\-(\d+);/) { 
+                    my $tmpstr = $result{'__RAW__'}->{"$_"} || "";
+                    if ($tmpstr =~ /$biblionumber,\Q$title\E\-(\d+);/) {
                         my $weight=$1+1;
                         $result{'__RAW__'}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d+);//;
                         $result{'__RAW__'}->{"$_"} .= "$biblionumber,$title-$weight;";
@@ -2657,7 +2917,7 @@ sub _AddBiblioNoZebra {
                         # it exists
                         if ($existing_biblionumbers) {
                             $result{'__RAW__'}->{"$_"} =$existing_biblionumbers;
-                            my $weight=$1+1;
+                            my $weight = ($1 ? $1 : 0) + 1;
                             $result{'__RAW__'}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d+);//;
                             $result{'__RAW__'}->{"$_"} .= "$biblionumber,$title-$weight;";
                         # create a new ligne for this entry
@@ -3248,9 +3508,8 @@ sub ModBiblioMarc {
 
     # deal with UNIMARC field 100 (encoding) : create it if needed & set encoding to unicode
     if ( $encoding eq "UNIMARC" ) {
-        my $string;
-        if ( length($record->subfield( 100, "a" )) == 35 ) {
-            $string = $record->subfield( 100, "a" );
+        my $string = $record->subfield( 100, "a" );
+        if ( ($string) && ( length($record->subfield( 100, "a" )) == 35 ) ) {
             my $f100 = $record->field(100);
             $record->delete_field($f100);
         }