Bug 4173: Followup: put the lib into a variable
[koha_fer] / C4 / AuthoritiesMarc.pm
index c92c319..79f3956 100644 (file)
@@ -26,6 +26,7 @@ use C4::AuthoritiesMarc::MARC21;
 use C4::AuthoritiesMarc::UNIMARC;
 use C4::Charset;
 use C4::Log;
+use Koha::Authority;
 
 use vars qw($VERSION @ISA @EXPORT);
 
@@ -199,7 +200,7 @@ sub SearchAuthorities {
         }
     } else {
         my $query;
-        my $attr;
+        my $attr = '';
             # the marclist may contain "mainentry". In this case, search the tag_to_report, that depends on
             # the authtypecode. Then, search on $a of this tag_to_report
             # also store main entry MARC tag, to extract it at end of search
@@ -230,9 +231,6 @@ sub SearchAuthorities {
                 elsif ( @$tags[$i] eq "mainentry" ) {
                     $attr = " \@attr 1=Heading ";
                 }
-                elsif ( @$tags[$i] eq "any" ) {
-                    $attr = " \@attr 1=Any ";
-                }
                 elsif ( @$tags[$i] eq "match" ) {
                     $attr = " \@attr 1=Match ";
                 }
@@ -245,6 +243,9 @@ sub SearchAuthorities {
                 elsif ( @$tags[$i] eq "thesaurus" ) {
                     $attr = " \@attr 1=Subject-heading-thesaurus ";
                 }
+                else { # Assume any if no index was specified
+                    $attr = " \@attr 1=Any ";
+                }
                 if ( @$operator[$i] eq 'is' ) {
                     $attr .= " \@attr 4=1  \@attr 5=100 "
                       ; ##Phrase, No truncation,all of subfield field must match
@@ -263,6 +264,9 @@ sub SearchAuthorities {
                 else {
                     $attr .= " \@attr 5=1 \@attr 4=6 "
                       ;    ## Word list, right truncated, anywhere
+                      if ($sortby eq 'Relevance') {
+                          $attr .= "\@attr 2=102 ";
+                      }
                 }
                 @$value[$i] =~ s/"/\\"/g; # Escape the double-quotes in the search value
                 $attr =$attr."\"".@$value[$i]."\"";
@@ -351,6 +355,10 @@ sub SearchAuthorities {
                         $reported_tag .= '$' . $_->[0] . $_->[1];
                     }
                 }
+                my $thisauthtype = GetAuthType(GetAuthTypeCode($authid));
+                $newline{authtype}     = defined ($thisauthtype) ?
+                                            $thisauthtype->{'authtypetext'} :
+                                            (GetAuthType($authtypecode) ? $_->{'authtypetext'} : '');
                 $newline{summary}      = $summary;
                 $newline{even}         = $counter % 2;
                 $newline{reported_tag} = $reported_tag;
@@ -844,19 +852,8 @@ Returns MARC::Record of the authority passed in parameter.
 
 sub GetAuthority {
     my ($authid)=@_;
-    my $dbh=C4::Context->dbh;
-    my $sth=$dbh->prepare("select authtypecode, marcxml from auth_header where authid=?");
-    $sth->execute($authid);
-    my ($authtypecode, $marcxml) = $sth->fetchrow;
-    my $record=eval {MARC::Record->new_from_xml(StripNonXmlChars($marcxml),'UTF-8',
-        (C4::Context->preference("marcflavour") eq "UNIMARC"?"UNIMARCAUTH":C4::Context->preference("marcflavour")))};
-    return undef if ($@);
-    $record->encoding('UTF-8');
-    if (C4::Context->preference("marcflavour") eq "MARC21") {
-      my ($auth_type_tag, $auth_type_subfield) = get_auth_type_location($authtypecode);
-      C4::AuthoritiesMarc::MARC21::fix_marc21_auth_type_location($record, $auth_type_tag, $auth_type_subfield);
-    }
-    return ($record);
+    my $authority = Koha::Authority->get_from_authid($authid);
+    return ($authority->record);
 }
 
 =head2 GetAuthType 
@@ -948,13 +945,14 @@ sub BuildSummary {
         $summary{type} = $authref->{authtypetext};
         $summary{summary} = $authref->{summary};
     }
-    my $marc21subfields = 'abcdfghjklmnopqrstuvxyz';
+    my $marc21subfields = 'abcdfghjklmnopqrstuvxyz68';
     my %marc21controlrefs = ( 'a' => 'earlier',
         'b' => 'later',
         'd' => 'acronym',
         'f' => 'musical',
         'g' => 'broader',
         'h' => 'narrower',
+        'n' => 'notapplicable',
         'i' => 'subfi',
         't' => 'parent'
     );
@@ -966,7 +964,6 @@ sub BuildSummary {
     $thesaurus{'5'}="Lieux";
     $thesaurus{'6'}="Sujets";
     #thesaurus a remplir
-    my @fields = $record->fields();
     my $reported_tag;
 # if the library has a summary defined, use it. Otherwise, build a standard one
 # FIXME - it appears that the summary field in the authority frameworks
@@ -1003,108 +1000,168 @@ sub BuildSummary {
         $resultstring =~ s/\[(.*?)\]//g;
         $resultstring =~ s/\n/<br>/g;
         $summary{summary}      =  $resultstring;
-    } else {
-        my @authorized;
-        my @notes;
-        my @seefrom;
-        my @seealso;
-        my @otherscript;
-        my @fields = $record->fields();
-        if (C4::Context->preference('marcflavour') eq 'UNIMARC') {
+    }
+    my @authorized;
+    my @notes;
+    my @seefrom;
+    my @seealso;
+    my @otherscript;
+    if (C4::Context->preference('marcflavour') eq 'UNIMARC') {
 # construct UNIMARC summary, that is quite different from MARC21 one
 # accepted form
-            foreach my $field ($record->field('2..')) {
-                push @authorized, $field->as_string('abcdefghijlmnopqrstuvwxyz');
-            }
+        foreach my $field ($record->field('2..')) {
+            push @authorized, { heading => $field->as_string('abcdefghijlmnopqrstuvwxyz'), field => $field->tag() };
+        }
 # rejected form(s)
-            foreach my $field ($record->field('3..')) {
-                push @notes, $field->subfield('a');
-            }
-            foreach my $field ($record->field('4..')) {
-                my $thesaurus = $field->subfield('2') ? "thes. : ".$thesaurus{"$field->subfield('2')"}." : " : '';
-                push @seefrom, { heading => $thesaurus . $field->as_string('abcdefghijlmnopqrstuvwxyz'), type => 'seefrom' };
-            }
+        foreach my $field ($record->field('3..')) {
+            push @notes, { note => $field->subfield('a'), field => $field->tag() };
+        }
+        foreach my $field ($record->field('4..')) {
+            my $thesaurus = $field->subfield('2') ? "thes. : ".$thesaurus{"$field->subfield('2')"}." : " : '';
+            push @seefrom, { heading => $thesaurus . $field->as_string('abcdefghijlmnopqrstuvwxyz'), type => 'seefrom', field => $field->tag() };
+        }
 # see :
-            foreach my $field ($record->field('5..')) {
-                if (($field->subfield('5')) && ($field->subfield('a')) && ($field->subfield('5') eq 'g')) {
-                    push @seealso, { $field->as_string('abcdefgjxyz'), type => 'broader' };
-                } elsif (($field->subfield('5')) && ($field->as_string) && ($field->subfield('5') eq 'h')){
-                    push @seealso, { heading => $field->as_string('abcdefgjxyz'), type => 'narrower' };
-                } elsif ($field->subfield('a')) {
-                    push @seealso, { heading => $field->as_string('abcdefgxyz'), type => 'seealso' };
-                }
+        foreach my $field ($record->field('5..')) {
+            if (($field->subfield('5')) && ($field->subfield('a')) && ($field->subfield('5') eq 'g')) {
+                push @seealso, {
+                    heading => $field->as_string('abcdefgjxyz'),
+                    type => 'broader',
+                    field => $field->tag(),
+                    search => $field->as_string('abcdefgjxyz'),
+                    authid => $field->subfield('9')
+                };
+            } elsif (($field->subfield('5')) && ($field->as_string) && ($field->subfield('5') eq 'h')){
+                push @seealso, {
+                    heading => $field->as_string('abcdefgjxyz'),
+                    type => 'narrower',
+                    field => $field->tag(),
+                    search => $field->as_string('abcdefgjxyz'),
+                    authid => $field->subfield('9')
+                };
+            } elsif ($field->subfield('a')) {
+                push @seealso, {
+                    heading => $field->as_string('abcdefgxyz'),
+                    type => 'seealso',
+                    field => $field->tag(),
+                    search => $field->as_string('abcdefgjxyz'),
+                    authid => $field->subfield('9')
+                };
             }
+        }
 # // form
-            foreach my $field ($record->field('7..')) {
-                my $lang = substr($field->subfield('8'),3,3);
-                push @otherscript, { lang => $lang, term => $field->subfield('a') };
-            }
-        } else {
+        foreach my $field ($record->field('7..')) {
+            my $lang = substr($field->subfield('8'),3,3);
+            push @otherscript, { lang => $lang, term => $field->subfield('a'), direction => 'ltr', field => $field->tag() };
+        }
+    } else {
 # construct MARC21 summary
 # FIXME - looping over 1XX is questionable
 # since MARC21 authority should have only one 1XX
-            foreach my $field ($record->field('1..')) {
-                my $tag = $field->tag();
-                next if "152" eq $tag;
+        my $subfields_to_report;
+        foreach my $field ($record->field('1..')) {
+            my $tag = $field->tag();
+            next if "152" eq $tag;
 # FIXME - 152 is not a good tag to use
 # in MARC21 -- purely local tags really ought to be
 # 9XX
-                if ($tag eq '100') {
-                    push @authorized, $field->as_string('abcdefghjklmnopqrstvxyz68');
-                } elsif ($tag eq '110') {
-                    push @authorized, $field->as_string('abcdefghklmnoprstvxyz68');
-                } elsif ($tag eq '111') {
-                    push @authorized, $field->as_string('acdefghklnpqstvxyz68');
-                } elsif ($tag eq '130') {
-                    push @authorized, $field->as_string('adfghklmnoprstvxyz68');
-                } elsif ($tag eq '148') {
-                    push @authorized, $field->as_string('abvxyz68');
-                } elsif ($tag eq '150') {
-                    push @authorized, $field->as_string('abvxyz68');
-                } elsif ($tag eq '151') {
-                    push @authorized, $field->as_string('avxyz68');
-                } elsif ($tag eq '155') {
-                    push @authorized, $field->as_string('abvxyz68');
-                } elsif ($tag eq '180') {
-                    push @authorized, $field->as_string('vxyz68');
-                } elsif ($tag eq '181') {
-                    push @authorized, $field->as_string('vxyz68');
-                } elsif ($tag eq '182') {
-                    push @authorized, $field->as_string('vxyz68');
-                } elsif ($tag eq '185') {
-                    push @authorized, $field->as_string('vxyz68');
-                } else {
-                    push @authorized, $field->as_string();
-                }
-            } #See From
-            foreach my $field ($record->field('4..')) {
-                my $type = 'seefrom';
-                $type = $marc21controlrefs{substr $field->subfield('w'), '0'} if ($field->subfield('w'));
-                if ($type eq 'subfi') {
-                    push @seefrom, { heading => $field->as_string($marc21subfields), type => $field->subfield('i') };
-                } else {
-                    push @seefrom, { heading => $field->as_string($marc21subfields), type => $type };
-                }
-            } #See Also
-            foreach my $field ($record->field('5..')) {
-                my $type = 'seealso';
-                $type = $marc21controlrefs{substr $field->subfield('w'), '0'} if ($field->subfield('w'));
-                if ($type eq 'subfi') {
-                    push @seealso, { heading => $field->as_string($marc21subfields), type => $field->subfield('i') };
-                } else {
-                    push @seealso, { heading => $field->as_string($marc21subfields), type => $type };
-                }
+            if ($tag eq '100') {
+                $subfields_to_report = 'abcdefghjklmnopqrstvxyz';
+            } elsif ($tag eq '110') {
+                $subfields_to_report = 'abcdefghklmnoprstvxyz';
+            } elsif ($tag eq '111') {
+                $subfields_to_report = 'acdefghklnpqstvxyz';
+            } elsif ($tag eq '130') {
+                $subfields_to_report = 'adfghklmnoprstvxyz';
+            } elsif ($tag eq '148') {
+                $subfields_to_report = 'abvxyz';
+            } elsif ($tag eq '150') {
+                $subfields_to_report = 'abvxyz';
+            } elsif ($tag eq '151') {
+                $subfields_to_report = 'avxyz';
+            } elsif ($tag eq '155') {
+                $subfields_to_report = 'abvxyz';
+            } elsif ($tag eq '180') {
+                $subfields_to_report = 'vxyz';
+            } elsif ($tag eq '181') {
+                $subfields_to_report = 'vxyz';
+            } elsif ($tag eq '182') {
+                $subfields_to_report = 'vxyz';
+            } elsif ($tag eq '185') {
+                $subfields_to_report = 'vxyz';
+            }
+            if ($subfields_to_report) {
+                push @authorized, { heading => $field->as_string($subfields_to_report), field => $tag };
+            } else {
+                push @authorized, { heading => $field->as_string(), field => $tag };
+            }
+        }
+        foreach my $field ($record->field('4..')) { #See From
+            my $type = 'seefrom';
+            $type = ($marc21controlrefs{substr $field->subfield('w'), 0, 1} || '') if ($field->subfield('w'));
+            if ($type eq 'notapplicable') {
+                $type = substr $field->subfield('w'), 2, 1;
+                $type = 'earlier' if $type && $type ne 'n';
             }
-            foreach my $field ($record->field('6..')) {
-                push @notes, $field->as_string();
+            if ($type eq 'subfi') {
+                push @seefrom, { heading => $field->as_string($marc21subfields), type => ($field->subfield('i') || ''), field => $field->tag() };
+            } else {
+                push @seefrom, { heading => $field->as_string($marc21subfields), type => $type, field => $field->tag() };
+            }
+        }
+        foreach my $field ($record->field('5..')) { #See Also
+            my $type = 'seealso';
+            $type = ($marc21controlrefs{substr $field->subfield('w'), 0, 1} || '') if ($field->subfield('w'));
+            if ($type eq 'notapplicable') {
+                $type = substr $field->subfield('w'), 2, 1;
+                $type = 'earlier' if $type && $type ne 'n';
+            }
+            if ($type eq 'subfi') {
+                push @seealso, {
+                    heading => $field->as_string($marc21subfields),
+                    type => $field->subfield('i'),
+                    field => $field->tag(),
+                    search => $field->as_string($marc21subfields) || '',
+                    authid => $field->subfield('9') || ''
+                };
+            } else {
+                push @seealso, {
+                    heading => $field->as_string($marc21subfields),
+                    type => $type,
+                    field => $field->tag(),
+                    search => $field->as_string($marc21subfields) || '',
+                    authid => $field->subfield('9') || ''
+                };
+            }
+        }
+        foreach my $field ($record->field('6..')) {
+            push @notes, { note => $field->as_string(), field => $field->tag() };
+        }
+        foreach my $field ($record->field('880')) {
+            my $linkage = $field->subfield('6');
+            my $category = substr $linkage, 0, 1;
+            if ($category eq '1') {
+                $category = 'preferred';
+            } elsif ($category eq '4') {
+                $category = 'seefrom';
+            } elsif ($category eq '5') {
+                $category = 'seealso';
+            }
+            my $type;
+            if ($field->subfield('w')) {
+                $type = $marc21controlrefs{substr $field->subfield('w'), '0'};
+            } else {
+                $type = $category;
             }
+            my $direction = $linkage =~ m#/r$# ? 'rtl' : 'ltr';
+            push @otherscript, { term => $field->as_string($subfields_to_report), category => $category, type => $type, direction => $direction, linkage => $linkage };
         }
-        $summary{authorized} = \@authorized;
-        $summary{notes} = \@notes;
-        $summary{seefrom} = \@seefrom;
-        $summary{seealso} = \@seealso;
-        $summary{otherscript} = \@otherscript;
     }
+    $summary{mainentry} = $authorized[0]->{heading};
+    $summary{authorized} = \@authorized;
+    $summary{notes} = \@notes;
+    $summary{seefrom} = \@seefrom;
+    $summary{seealso} = \@seealso;
+    $summary{otherscript} = \@otherscript;
     return \%summary;
 }
 
@@ -1306,8 +1363,8 @@ sub merge {
     } else {
         #zebra connection  
         my $oConnection=C4::Context->Zconn("biblioserver",0);
-        my $oldSyntax = $oConnection->option("preferredRecordSyntax");
-        $oConnection->option("preferredRecordSyntax"=>"XML");
+        # We used to use XML syntax here, but that no longer works.
+        # Thankfully, we don't need it.
         my $query;
         $query= "an=".$mergefrom;
         my $oResult = $oConnection->search(new ZOOM::Query::CCL2RPN( $query, $oConnection ));
@@ -1320,15 +1377,14 @@ sub merge {
             my $rec;
             $rec=$oResult->record($z);
             my $marcdata = $rec->raw();
-            my $marcrecordzebra= MARC::Record->new_from_xml($marcdata,"utf8",C4::Context->preference("marcflavour"));
+            my $marcrecordzebra= MARC::Record->new_from_usmarc($marcdata);
             my ( $biblionumbertagfield, $biblionumbertagsubfield ) = &GetMarcFromKohaField( "biblio.biblionumber", '' );
-            my $i = $marcrecordzebra->subfield($biblionumbertagfield, $biblionumbertagsubfield);
+            my $i = ($biblionumbertagfield < 10) ? $marcrecordzebra->field($biblionumbertagfield)->data : $marcrecordzebra->subfield($biblionumbertagfield, $biblionumbertagsubfield);
             my $marcrecorddb=GetMarcBiblio($i);
             push @reccache, $marcrecorddb;
             $z++;
         }
         $oResult->destroy();
-        $oConnection->option("preferredRecordSyntax"=>$oldSyntax);
     }
     #warn scalar(@reccache)." biblios to update";
     # Get All candidate Tags for the change 
@@ -1353,12 +1409,13 @@ sub merge {
         foreach my $tagfield (@tags_using_authtype){
 #             warn "tagfield : $tagfield ";
             foreach my $field ($marcrecord->field($tagfield)){
+                # biblio is linked to authority with $9 subfield containing authid
                 my $auth_number=$field->subfield("9");
                 my $tag=$field->tag();          
                 if ($auth_number==$mergefrom) {
                 my $field_to=MARC::Field->new(($tag_to?$tag_to:$tag),$field->indicator(1),$field->indicator(2),"9"=>$mergeto);
                my $exclude='9';
-                foreach my $subfield (@record_to) {
+                foreach my $subfield (grep {$_->[0] ne '9'} @record_to) {
                     $field_to->add_subfields($subfield->[0] =>$subfield->[1]);
                    $exclude.= $subfield->[0];
                 }