(bug #3281) change the way to parse item's summary
[koha-ffzg.git] / C4 / Biblio.pm
old mode 100644 (file)
new mode 100755 (executable)
index 04d404c..a0c325a
@@ -50,6 +50,7 @@ BEGIN {
 
        # to get something
        push @EXPORT, qw(
+           &Get
                &GetBiblio
                &GetBiblioData
                &GetBiblioItemData
@@ -57,6 +58,11 @@ BEGIN {
                &GetBiblioItemByBiblioNumber
                &GetBiblioFromItemNumber
                
+               &GetRecordValue
+               &GetFieldMapping
+               &SetFieldMapping
+               &DeleteFieldMapping
+               
                &GetISBDView
 
                &GetMarcNotes
@@ -492,6 +498,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
@@ -846,12 +961,12 @@ sub GetMarcStructure {
         return $marc_structure_cache->{$forlibrarian}->{$frameworkcode};
     }
 
+#     my $sth = $dbh->prepare(
+#         "SELECT COUNT(*) FROM marc_tag_structure WHERE frameworkcode=?");
+#     $sth->execute($frameworkcode);
+#     my ($total) = $sth->fetchrow;
+#     $frameworkcode = "" unless ( $total > 0 );
     my $sth = $dbh->prepare(
-        "SELECT COUNT(*) FROM marc_tag_structure WHERE frameworkcode=?");
-    $sth->execute($frameworkcode);
-    my ($total) = $sth->fetchrow;
-    $frameworkcode = "" unless ( $total > 0 );
-    $sth = $dbh->prepare(
         "SELECT tagfield,liblibrarian,libopac,mandatory,repeatable 
         FROM marc_tag_structure 
         WHERE frameworkcode=? 
@@ -1158,19 +1273,22 @@ sub GetCOinSBiblio {
 =over 4
 
 my $subfieldvalue =get_authorised_value_desc(
-    $tag, $subf[$i][0],$subf[$i][1], '', $taglib, $category);
+    $tag, $subf[$i][0],$subf[$i][1], '', $taglib, $category, $opac);
 Retrieve the complete description for a given authorised value.
 
 Now takes $category and $value pair too.
 my $auth_value_desc =GetAuthorisedValueDesc(
     '','', 'DVD' ,'','','CCODE');
 
+If the optional $opac parameter is set to a true value, displays OPAC descriptions rather than normal ones when they exist.
+
+
 =back
 
 =cut
 
 sub GetAuthorisedValueDesc {
-    my ( $tag, $subfield, $value, $framework, $tagslib, $category ) = @_;
+    my ( $tag, $subfield, $value, $framework, $tagslib, $category, $opac ) = @_;
     my $dbh = C4::Context->dbh;
 
     if (!$category) {
@@ -1194,11 +1312,11 @@ sub GetAuthorisedValueDesc {
     if ( $category ne "" ) {
         my $sth =
             $dbh->prepare(
-                    "SELECT lib FROM authorised_values WHERE category = ? AND authorised_value = ?"
+                    "SELECT lib, lib_opac FROM authorised_values WHERE category = ? AND authorised_value = ?"
                     );
         $sth->execute( $category, $value );
         my $data = $sth->fetchrow_hashref;
-        return $data->{'lib'};
+        return ($opac && $data->{'lib_opac'}) ? $data->{'lib_opac'} : $data->{'lib'};
     }
     else {
         return $value;    # if nothing is found return the original value
@@ -1285,10 +1403,10 @@ sub GetMarcSubjects {
         my $counter = 0;
         my @link_loop;
         # if there is an authority link, build the link with an= subfield9
-        my $subfield9 = $field->subfield('9');
+               my $found9=0;
         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/ ) );
+            next if (($marcflavour eq "UNIMARC") and ($subject_subfield->[0] =~ /2|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];
@@ -1296,11 +1414,13 @@ sub GetMarcSubjects {
             my $linkvalue = $value;
             $linkvalue =~ s/(\(|\))//g;
             my $operator = " and " unless $counter==0;
-            if ($subfield9) {
-                @link_loop = ({'limit' => 'an' ,link => "$subfield9" });
-            } else {
-                push @link_loop, {'limit' => 'su', link => $linkvalue, operator => $operator };
-            }
+            if ($code eq 9) {
+                               $found9 = 1;
+                @link_loop = ({'limit' => 'an' ,link => "$linkvalue" });
+                       }
+                       if (not $found9) {
+                               push @link_loop, {'limit' => 'su', link => $linkvalue, operator => $operator };
+                       }
             my $separator = C4::Context->preference("authoritysep") unless $counter==0;
             # ignore $9
             my @this_link_loop = @link_loop;
@@ -1675,10 +1795,10 @@ sub TransformHtmlToXml {
                 if (   ( @$tags[$i] && @$tags[$i] > 10 )
                     && ( @$values[$i] ne "" ) )
                 {
-                    my $ind1 = substr( @$indicator[$j], 0, 1 );
+                    my $ind1 = _default_ind_to_space(substr( @$indicator[$j], 0, 1 ));
                     my $ind2;
                     if ( @$indicator[$j] ) {
-                        $ind2 = substr( @$indicator[$j], 1, 1 );
+                        $ind2 = _default_ind_to_space(substr( @$indicator[$j], 1, 1 ));
                     }
                     else {
                         warn "Indicator in @$tags[$i] is empty";
@@ -1707,10 +1827,8 @@ 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 "";
+                        my $ind1 = _default_ind_to_space( substr( @$indicator[$j], 0, 1 ) );
+                        my $ind2 = _default_ind_to_space( substr( @$indicator[$j], 1, 1 ) );
                         $xml .= "<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
                         $xml .= "<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
                         $first = 0;
@@ -1723,10 +1841,8 @@ sub TransformHtmlToXml {
             }
             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 "";
+                    my $ind1 = _default_ind_to_space( substr( @$indicator[$j], 0, 1 ) );
+                    my $ind2 = _default_ind_to_space( substr( @$indicator[$j], 1, 1 ) );
                     $xml .= "<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
                     $first = 0;
                 }
@@ -1753,6 +1869,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>)
@@ -1825,8 +1956,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;
             
@@ -1855,8 +1986,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]),
                             );
                         }
@@ -2149,23 +2280,27 @@ sub TransformMarcToKohaOneField {
 
 =over 4
 
-PrepareItemrecordDisplay($itemrecord,$bibnum,$itemumber);
+PrepareItemrecordDisplay($itemrecord,$bibnum,$itemumber,$frameworkcode);
 
 Returns a hash with all the fields for Display a given item data in a template
 
+The $frameworkcode returns the item for the given frameworkcode, ONLY if bibnum is not provided
+
 =back
 
 =cut
 
 sub PrepareItemrecordDisplay {
 
-    my ( $bibnum, $itemnum, $defaultvalues ) = @_;
+    my ( $bibnum, $itemnum, $defaultvalues, $frameworkcode ) = @_;
 
     my $dbh = C4::Context->dbh;
-    my $frameworkcode = &GetFrameworkCode( $bibnum );
+    $frameworkcode = &GetFrameworkCode( $bibnum ) if $bibnum;
     my ( $itemtagfield, $itemtagsubfield ) =
       &GetMarcFromKohaField( "items.itemnumber", $frameworkcode );
     my $tagslib = &GetMarcStructure( 1, $frameworkcode );
+    # return nothing if we don't have found an existing framework.
+    return "" unless $tagslib;
     my $itemrecord = C4::Items::GetMarcItem( $bibnum, $itemnum) if ($itemnum);
     my @loop_data;
     my $authorised_values_sth =
@@ -2220,22 +2355,22 @@ sub PrepareItemrecordDisplay {
                 }
                 if ( $tagslib->{$tag}->{$subfield}->{kohafield} eq
                     'items.itemcallnumber'
-                    && $defaultvalues->{'callnumber'} )
+                    && $defaultvalues && $defaultvalues->{'callnumber'} )
                 {
                     my $temp = $itemrecord->field($subfield) if ($itemrecord);
                     unless ($temp) {
-                        $value = $defaultvalues->{'callnumber'};
+                        $value = $defaultvalues->{'callnumber'} if $defaultvalues;
                     }
                 }
                 if ( ($tagslib->{$tag}->{$subfield}->{kohafield} eq
                     'items.holdingbranch' ||
                     $tagslib->{$tag}->{$subfield}->{kohafield} eq
                     'items.homebranch')          
-                    && $defaultvalues->{'branchcode'} )
+                    && $defaultvalues && $defaultvalues->{'branchcode'} )
                 {
                     my $temp = $itemrecord->field($subfield) if ($itemrecord);
                     unless ($temp) {
-                        $value = $defaultvalues->{branchcode};
+                        $value = $defaultvalues->{branchcode}  if $defaultvalues;
                     }
                 }
                 if ( $tagslib->{$tag}->{$subfield}->{authorised_value} ) {
@@ -2669,7 +2804,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;";
@@ -2680,7 +2816,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
@@ -3271,9 +3407,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);
         }