fix permissions error introduced by previous patch
[koha.git] / C4 / Biblio.pm
index cee44d5..24c60ff 100644 (file)
@@ -26,12 +26,15 @@ use MARC::File::USMARC;
 #$XML::SAX::ParserPackage = "XML::LibXML::SAX";
 use MARC::File::XML;
 use ZOOM;
+use POSIX qw(strftime);
 
 use C4::Koha;
 use C4::Dates qw/format_date/;
 use C4::Log; # logaction
 use C4::ClassSource;
 use C4::Charset;
+require C4::Heading;
+require C4::Serials;
 
 use vars qw($VERSION @ISA @EXPORT);
 
@@ -55,6 +58,8 @@ BEGIN {
                &GetBiblioItemInfosOf
                &GetBiblioItemByBiblioNumber
                &GetBiblioFromItemNumber
+               
+               &GetISBDView
 
                &GetMarcNotes
                &GetMarcSubjects
@@ -285,25 +290,10 @@ sub ModBiblio {
     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);
-    }
-    
+   
+    # once all the items fields are removed, copy the old ones, in order to keep synchronize
+    $record->append_fields($oldRecord->field( $itemtag ));
+   
     # update biblionumber and biblioitemnumber in MARC
     # FIXME - this is assuming a 1 to 1 relationship between
     # biblios and biblioitems
@@ -376,6 +366,12 @@ sub DelBiblio {
 
     return $error if $error;
 
+    # We delete attached subscriptions
+    my $subscriptions = &C4::Serials::GetFullSubscriptionsFromBiblionumber($biblionumber);
+    foreach my $subscription (@$subscriptions){
+        &C4::Serials::DelSubscription($subscription->{subscriptionid});
+    }
+    
     # Delete in Zebra. Be careful NOT to move this line after _koha_delete_biblio
     # for at least 2 reasons :
     # - we need to read the biblio if NoZebra is set (to remove it from the indexes
@@ -614,6 +610,138 @@ sub GetBiblioFromItemNumber {
     return ($data);
 }
 
+=head2 GetISBDView 
+
+=over 4
+
+$isbd = &GetISBDView($biblionumber);
+
+Return the ISBD view which can be included in opac and intranet
+
+=back
+
+=cut
+
+sub GetISBDView {
+    my $biblionumber    = shift;
+    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');
+    my $bloc = $ISBD;
+    my $res;
+    my $blocres;
+    
+    foreach my $isbdfield ( split (/#/, $bloc) ) {
+
+        #         $isbdfield= /(.?.?.?)/;
+        $isbdfield =~ /(\d\d\d)([^\|])?\|(.*)\|(.*)\|(.*)/;
+        my $fieldvalue    = $1 || 0;
+        my $subfvalue     = $2 || "";
+        my $textbefore    = $3;
+        my $analysestring = $4;
+        my $textafter     = $5;
+    
+        #         warn "==> $1 / $2 / $3 / $4";
+        #         my $fieldvalue=substr($isbdfield,0,3);
+        if ( $fieldvalue > 0 ) {
+            my $hasputtextbefore = 0;
+            my @fieldslist = $record->field($fieldvalue);
+            @fieldslist = sort {$a->subfield($holdingbrtagsubf) cmp $b->subfield($holdingbrtagsubf)} @fieldslist if ($fieldvalue eq $holdingbrtagf);
+    
+            #         warn "ERROR IN ISBD DEFINITION at : $isbdfield" unless $fieldvalue;
+            #             warn "FV : $fieldvalue";
+            if ($subfvalue ne ""){
+              foreach my $field ( @fieldslist ) {
+                foreach my $subfield ($field->subfield($subfvalue)){ 
+                  my $calculated = $analysestring;
+                  my $tag        = $field->tag();
+                  if ( $tag < 10 ) {
+                  }
+                  else {
+                    my $subfieldvalue =
+                    GetAuthorisedValueDesc( $tag, $subfvalue,
+                      $subfield, '', $tagslib );
+                    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 )
+                    {    # put textbefore if not done
+                    $blocres .= $textbefore;
+                    $hasputtextbefore = 1;
+                    }
+                
+                    # remove punctuation at start
+                    $calculated =~ s/^( |;|:|\.|-)*//g;
+                    $blocres .= $calculated;
+                                
+                  }
+                }
+              }
+              $blocres .= $textafter if $hasputtextbefore;
+            } else {    
+            foreach my $field ( @fieldslist ) {
+              my $calculated = $analysestring;
+              my $tag        = $field->tag();
+              if ( $tag < 10 ) {
+              }
+              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;
+                }
+    
+                # field builded, store the result
+                if ( $calculated && !$hasputtextbefore )
+                {    # put textbefore if not done
+                $blocres .= $textbefore;
+                $hasputtextbefore = 1;
+                }
+    
+                # remove punctuation at start
+                $calculated =~ s/^( |;|:|\.|-)*//g;
+                $blocres .= $calculated;
+              }
+            }
+            $blocres .= $textafter if $hasputtextbefore;
+            }       
+        }
+        else {
+            $blocres .= $isbdfield;
+        }
+    }
+    $res .= $blocres;
+    
+    $res =~ s/\{(.*?)\}//g;
+    $res =~ s/\\n/\n/g;
+    $res =~ s/\n/<br\/>/g;
+    
+    # remove empty ()
+    $res =~ s/\(\)//g;
+   
+    return $res;
+}
+
 =head2 GetBiblio
 
 =over 4
@@ -902,7 +1030,8 @@ Returns the COinS(a span) which can be included in a biblio record
 sub GetCOinSBiblio {
     my ( $biblionumber ) = @_;
     my $record = GetMarcBiblio($biblionumber);
-
+    my $coins_value;
+    if (defined $record){
     # get the coin format
     my $pos7 = substr $record->leader(), 7,1;
     my $pos6 = substr $record->leader(), 6,1;
@@ -911,6 +1040,7 @@ sub GetCOinSBiblio {
     my ($aulast, $aufirst);
     my $oauthors;
     my $title;
+    my $subtitle;
     my $pubyear;
     my $isbn;
     my $issn;
@@ -990,17 +1120,19 @@ sub GetCOinSBiblio {
                 $oauthors .= "&rft.au=$au";
             }
         }
-        $title      = "&rft.btitle=".$record->subfield('245','a');
-        $pubyear    = $record->subfield('260','c');
-        $publisher  = $record->subfield('260','b');
-        $isbn       = $record->subfield('020','a');
-        $issn       = $record->subfield('022','a');
+        $title      = "&amp;rft.btitle=".$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') || '';
 
     }
-    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";
+    $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";
     $coins_value =~ s/\ /\+/g;
     #<!-- TMPL_VAR NAME="ocoins_format" -->&amp;rft.au=<!-- TMPL_VAR NAME="author" -->&amp;rft.btitle=<!-- TMPL_VAR NAME="title" -->&amp;rft.date=<!-- TMPL_VAR NAME="publicationyear" -->&amp;rft.pages=<!-- TMPL_VAR NAME="pages" -->&amp;rft.isbn=<!-- TMPL_VAR NAME=amazonisbn -->&amp;rft.aucorp=&amp;rft.place=<!-- TMPL_VAR NAME="place" -->&amp;rft.pub=<!-- TMPL_VAR NAME="publishercode" -->&amp;rft.edition=<!-- TMPL_VAR NAME="edition" -->&amp;rft.series=<!-- TMPL_VAR NAME="series" -->&amp;rft.genre="
-
+    }
     return $coins_value;
 }
 
@@ -1142,6 +1274,8 @@ sub GetMarcSubjects {
         for my $subject_subfield (@subfields ) {
             # don't load unimarc subfields 3,4,5
             next if (($marcflavour eq "UNIMARC") and ($subject_subfield->[0] =~ /3|4|5/ ) );
+            # don't load MARC21 subfields 2 (FIXME: any more subfields??)
+            next if (($marcflavour eq "MARC21")  and ($subject_subfield->[0] =~ /2/ ) );
             my $code = $subject_subfield->[0];
             my $value = $subject_subfield->[1];
             my $linkvalue = $value;
@@ -1246,44 +1380,48 @@ Assumes web resources (not uncommon in MARC21 to omit resource type ind)
 =cut
 
 sub GetMarcUrls {
-    my ($record, $marcflavour) = @_;
+    my ( $record, $marcflavour ) = @_;
+
     my @marcurls;
-    for my $field ($record->field('856')) {
+    for my $field ( $record->field('856') ) {
         my $marcurl;
-        my $url = $field->subfield('u');
         my @notes;
-        for my $note ( $field->subfield('z')) {
-            push @notes , {note => $note};
-        }        
-        if($marcflavour eq 'MARC21') {
-            my $s3 = $field->subfield('3');
-            my $link = $field->subfield('y');
-                       unless($url =~ /^\w+:/) {
-                               if($field->indicator(1) eq '7') {
-                                       $url = $field->subfield('2') . "://" . $url;
-                               } elsif ($field->indicator(1) eq '1') {
-                                       $url = 'ftp://' . $url;
-                               } else {  
-                                       #  properly, this should be if ind1=4,
-                                       #  however we will assume http protocol since we're building a link.
-                                       $url = 'http://' . $url;
-                               }
-                       }
-                       # TODO handle ind 2 (relationship)
-               $marcurl = {  MARCURL => $url,
-                      notes => \@notes,
-            };
-            $marcurl->{'linktext'} = $link || $s3 || C4::Context->preference('URLLinkText') || $url ;;
-            $marcurl->{'part'} = $s3 if($link);
-            $marcurl->{'toc'} = 1 if($s3 =~ /^[Tt]able/) ;
-        } else {
-            $marcurl->{'linktext'} = $field->subfield('z') || C4::Context->preference('URLLinkText') || $url;
-            $marcurl->{'MARCURL'} = $url ;
+        for my $note ( $field->subfield('z') ) {
+            push @notes, { note => $note };
+        }
+        my @urls = $field->subfield('u');
+        foreach my $url (@urls) {
+            if ( $marcflavour eq 'MARC21' ) {
+                my $s3   = $field->subfield('3');
+                my $link = $field->subfield('y');
+                unless ( $url =~ /^\w+:/ ) {
+                    if ( $field->indicator(1) eq '7' ) {
+                        $url = $field->subfield('2') . "://" . $url;
+                    } elsif ( $field->indicator(1) eq '1' ) {
+                        $url = 'ftp://' . $url;
+                    } else {
+                        #  properly, this should be if ind1=4,
+                        #  however we will assume http protocol since we're building a link.
+                        $url = 'http://' . $url;
+                    }
+                }
+                # TODO handle ind 2 (relationship)
+                $marcurl = {
+                    MARCURL => $url,
+                    notes   => \@notes,
+                };
+                $marcurl->{'linktext'} = $link || $s3 || C4::Context->preference('URLLinkText') || $url;
+                $marcurl->{'part'} = $s3 if ($link);
+                $marcurl->{'toc'} = 1 if ( defined($s3) && $s3 =~ /^table/i );
+            } else {
+                $marcurl->{'linktext'} = $field->subfield('2') || C4::Context->preference('URLLinkText') || $url;
+                $marcurl->{'MARCURL'} = $url;
+            }
+            push @marcurls, $marcurl;
         }
-        push @marcurls, $marcurl;    
     }
     return \@marcurls;
-}  #end GetMarcUrls
+}
 
 =head2 GetMarcSeries
 
@@ -1417,18 +1555,15 @@ sub GetPublisherNameFromIsbn($){
 =cut
 
 sub TransformKohaToMarc {
-
     my ( $hash ) = @_;
-    my $dbh = C4::Context->dbh;
-    my $sth =
-    $dbh->prepare(
+    my $sth = C4::Context->dbh->prepare(
         "SELECT tagfield,tagsubfield FROM marc_subfield_structure WHERE frameworkcode=? AND kohafield=?"
     );
     my $record = MARC::Record->new();
+    SetMarcUnicodeFlag($record, C4::Context->preference("marcflavour"));
     foreach (keys %{$hash}) {
-        &TransformKohaToMarcOneField( $sth, $record, $_,
-            $hash->{$_}, '' );
-        }
+        &TransformKohaToMarcOneField( $sth, $record, $_, $hash->{$_}, '' );
+    }
     return $record;
 }
 
@@ -1590,7 +1725,6 @@ sub TransformHtmlToXml {
     $xml .= "</datafield>\n" if @$tags > 0;
     if (C4::Context->preference('marcflavour') eq 'UNIMARC' and !$unimarc_and_100_exist) {
 #     warn "SETTING 100 for $auth_type";
-        use POSIX qw(strftime);
         my $string = strftime( "%Y%m%d", localtime(time) );
         # set 50 to position 26 is biblios, 13 if authorities
         my $pos=26;
@@ -2164,21 +2298,6 @@ sub PrepareItemrecordDisplay {
                         -multiple => 0,
                     );
                 }
-                elsif ( $tagslib->{$tag}->{$subfield}->{thesaurus_category} ) {
-                    $subfield_data{marc_value} =
-"<input type=\"text\" name=\"field_value\"  size=\"47\" maxlength=\"255\" /> <a href=\"javascript:Dopop('cataloguing/thesaurus_popup.pl?category=$tagslib->{$tag}->{$subfield}->{thesaurus_category}&index=',)\">...</a>";
-
-#"
-# COMMENTED OUT because No $i is provided with this API.
-# And thus, no value_builder can be activated.
-# BUT could be thought over.
-#         } elsif ($tagslib->{$tag}->{$subfield}->{'value_builder'}) {
-#             my $plugin="value_builder/".$tagslib->{$tag}->{$subfield}->{'value_builder'};
-#             require $plugin;
-#             my $extended_param = plugin_parameters($dbh,$itemrecord,$tagslib,$i,0);
-#             my ($function_name,$javascript) = plugin_javascript($dbh,$record,$tagslib,$i,0);
-#             $subfield_data{marc_value}="<input type=\"text\" value=\"$value\" name=\"field_value\"  size=47 maxlength=255 DISABLE READONLY OnFocus=\"javascript:Focus$function_name()\" OnBlur=\"javascript:Blur$function_name()\"> <a href=\"javascript:Clic$function_name()\">...</a> $javascript";
-                }
                 else {
                     $subfield_data{marc_value} =
 "<input type=\"text\" name=\"field_value\" value=\"$value\" size=\"50\" maxlength=\"255\" />";
@@ -3272,6 +3391,7 @@ sub set_service_options {
 
   parameters:
     biblionumber
+    MARC::Record of the bib
 
   returns: a hashref malling the authorised value to the value set for this biblionumber
 
@@ -3288,14 +3408,13 @@ sub set_service_options {
 
 sub get_biblio_authorised_values {
     my $biblionumber = shift;
+    my $record       = shift;
     
     my $forlibrarian = 1; # are we in staff or opac?
     my $frameworkcode = GetFrameworkCode( $biblionumber );
 
     my $authorised_values;
 
-    my $record  = GetMarcBiblio( $biblionumber )
-      or return $authorised_values;
     my $tagslib = GetMarcStructure( $forlibrarian, $frameworkcode )
       or return $authorised_values;