Bug 9044: (follow-up) fix merge conflict typo that broke this script
[koha.git] / C4 / AuthoritiesMarc.pm
index 2671cd4..7443f36 100644 (file)
@@ -109,281 +109,213 @@ sub SearchAuthorities {
     my ($tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode,$sortby,$skipmetadata) = @_;
     # warn Dumper($tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode,$sortby);
     my $dbh=C4::Context->dbh;
-    if (C4::Context->preference('NoZebra')) {
-    
-        #
-        # build the query
-        #
-        my $query;
+    my $query;
+    my $qpquery = '';
+    my $QParser;
+    $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser'));
+    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
+    my $mainentrytag;
+    ##first set the authtype search and may be multiple authorities
+    if ($authtypecode) {
+        my $n=0;
+        my @authtypecode;
         my @auths=split / /,$authtypecode ;
         foreach my  $auth (@auths){
-            $query .="AND auth_type= $auth ";
+            $query .=" \@attr 1=authtype \@attr 5=100 ".$auth; ##No truncation on authtype
+                push @authtypecode ,$auth;
+            $n++;
         }
-        $query =~ s/^AND //;
-        my $dosearch;
-        for(my $i = 0 ; $i <= $#{$value} ; $i++)
-        {
-            if (@$value[$i]){
-                if (@$tags[$i] =~/mainentry|mainmainentry/) {
-                    $query .= qq( AND @$tags[$i] );
-                } else {
-                    $query .=" AND ";
-                }
-                if (@$operator[$i] eq 'is') {
-                    $query.=(@$tags[$i]?"=":""). '"'.@$value[$i].'"';
-                }elsif (@$operator[$i] eq "="){
-                    $query.=(@$tags[$i]?"=":""). '"'.@$value[$i].'"';
-                }elsif (@$operator[$i] eq "start"){
-                    $query.=(@$tags[$i]?"=":"").'"'.@$value[$i].'%"';
-                } else {
-                    $query.=(@$tags[$i]?"=":"").'"'.@$value[$i].'%"';
-                }
-                $dosearch=1;
-            }#if value
+        if ($n>1){
+            while ($n>1){$query= "\@or ".$query;$n--;}
         }
-        #
-        # do the query (if we had some search term
-        #
-        if ($dosearch) {
-#             warn "QUERY : $query";
-            my $result = C4::Search::NZanalyse($query,'authorityserver');
-#             warn "result : $result";
-            my %result;
-            foreach (split /;/,$result) {
-                my ($authid,$title) = split /,/,$_;
-                # hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
-                # and we don't want to get only 1 result for each of them !!!
-                # hint & speed improvement : we can order without reading the record
-                # so order, and read records only for the requested page !
-                $result{$title.$authid}=$authid;
+        if ($QParser) {
+            $qpquery .= '(authtype:' . join('|| authtype:', @auths) . ')';
+        }
+    }
+
+    my $dosearch;
+    my $and=" \@and " ;
+    my $q2;
+    my $attr_cnt = 0;
+    for(my $i = 0 ; $i <= $#{$value} ; $i++)
+    {
+        if (@$value[$i]){
+            if ( @$tags[$i] eq "mainmainentry" ) {
+                $attr = " \@attr 1=Heading-Main ";
             }
-            # sort the hash and return the same structure as GetRecords (Zebra querying)
-            my @listresult = ();
-            my $numbers=0;
-            if ($sortby eq 'HeadingDsc') { # sort by mainmainentry desc
-                foreach my $key (sort {$b cmp $a} (keys %result)) {
-                    push @listresult, $result{$key};
-#                     warn "push..."$#finalresult;
-                    $numbers++;
-                }
-            } else { # sort by mainmainentry ASC
-                foreach my $key (sort (keys %result)) {
-                    push @listresult, $result{$key};
-#                     warn "push..."$#finalresult;
-                    $numbers++;
-                }
+            elsif ( @$tags[$i] eq "mainentry" ) {
+                $attr = " \@attr 1=Heading ";
             }
-            # limit the $results_per_page to result size if it's more
-            $length = $numbers-$offset if $numbers < ($offset+$length);
-            # for the requested page, replace authid by the complete record
-            # speed improvement : avoid reading too much things
-            my @finalresult;      
-            for (my $counter=$offset;$counter<=$offset+$length-1;$counter++) {
-#                 $finalresult[$counter] = GetAuthority($finalresult[$counter])->as_usmarc;
-                my $separator=C4::Context->preference('authoritysep');
-                my $authrecord =GetAuthority($listresult[$counter]);
-                my $authid=$listresult[$counter]; 
-                my $summary=BuildSummary($authrecord,$authid,$authtypecode);
-                my $query_auth_tag = "SELECT auth_tag_to_report FROM auth_types WHERE authtypecode=?";
-                my $sth = $dbh->prepare($query_auth_tag);
-                $sth->execute($authtypecode);
-                my $auth_tag_to_report = $sth->fetchrow;
-                my %newline;
-                $newline{used}=CountUsage($authid);
-                $newline{summary} = $summary;
-                $newline{authid} = $authid;
-                $newline{even} = $counter % 2;
-                push @finalresult, \%newline;
+            elsif ( @$tags[$i] eq "match" ) {
+                $attr = " \@attr 1=Match ";
             }
-            return (\@finalresult, $numbers);
-        } else {
-            return;
-        }
-    } else {
-        my $query;
-        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
-        my $mainentrytag;
-        ##first set the authtype search and may be multiple authorities
-        if ($authtypecode) {
-            my $n=0;
-            my @authtypecode;
-            my @auths=split / /,$authtypecode ;
-            foreach my  $auth (@auths){
-                $query .=" \@attr 1=authtype \@attr 5=100 ".$auth; ##No truncation on authtype
-                    push @authtypecode ,$auth;
-                $n++;
+            elsif ( @$tags[$i] eq "match-heading" ) {
+                $attr = " \@attr 1=Match-heading ";
             }
-            if ($n>1){
-                while ($n>1){$query= "\@or ".$query;$n--;}
+            elsif ( @$tags[$i] eq "see-from" ) {
+                $attr = " \@attr 1=Match-heading-see-from ";
             }
+            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
+            }
+            elsif ( @$operator[$i] eq "=" ) {
+                $attr .= " \@attr 4=107 ";    #Number Exact match
+            }
+            elsif ( @$operator[$i] eq "start" ) {
+                $attr .= " \@attr 3=2 \@attr 4=1 \@attr 5=1 "
+                  ;    #Firstinfield Phrase, Right truncated
+            }
+            elsif ( @$operator[$i] eq "exact" ) {
+                $attr .= " \@attr 4=1  \@attr 5=100 \@attr 6=3 "
+                  ; ##Phrase, No truncation,all of subfield field must match
+            }
+            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]."\"";
+            $q2 .=$attr;
+            $dosearch=1;
+            ++$attr_cnt;
+            if ($QParser) {
+                $qpquery .= " $tags->[$i]:\"$value->[$i]\"";
+            }
+        }#if value
+    }
+    ##Add how many queries generated
+    if (defined $query && $query=~/\S+/){
+      $query= $and x $attr_cnt . $query . (defined $q2 ? $q2 : '');
+    } else {
+      $query= $q2;
+    }
+    ## Adding order
+    #$query=' @or  @attr 7=2 @attr 1=Heading 0 @or  @attr 7=1 @attr 1=Heading 1'.$query if ($sortby eq "HeadingDsc");
+    my $orderstring;
+    if ($sortby eq 'HeadingAsc') {
+        $orderstring = '@attr 7=1 @attr 1=Heading 0';
+    } elsif ($sortby eq 'HeadingDsc') {
+        $orderstring = '@attr 7=2 @attr 1=Heading 0';
+    } elsif ($sortby eq 'AuthidAsc') {
+        $orderstring = '@attr 7=1 @attr 4=109 @attr 1=Local-Number 0';
+    } elsif ($sortby eq 'AuthidDsc') {
+        $orderstring = '@attr 7=2 @attr 4=109 @attr 1=Local-Number 0';
+    }
+    if ($QParser) {
+        $qpquery .= ' all:all' unless $value->[0];
+
+        if ( $value->[0] =~ m/^qp=(.*)$/ ) {
+            $qpquery = $1;
         }
-        
-        my $dosearch;
-        my $and=" \@and " ;
-        my $q2;
-        my $attr_cnt = 0;
-        for(my $i = 0 ; $i <= $#{$value} ; $i++)
-        {
-            if (@$value[$i]){
-                if ( @$tags[$i] eq "mainmainentry" ) {
-                    $attr = " \@attr 1=Heading-Main ";
-                }
-                elsif ( @$tags[$i] eq "mainentry" ) {
-                    $attr = " \@attr 1=Heading ";
-                }
-                elsif ( @$tags[$i] eq "match" ) {
-                    $attr = " \@attr 1=Match ";
-                }
-                elsif ( @$tags[$i] eq "match-heading" ) {
-                    $attr = " \@attr 1=Match-heading ";
-                }
-                elsif ( @$tags[$i] eq "see-from" ) {
-                    $attr = " \@attr 1=Match-heading-see-from ";
-                }
-                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
-                }
-                elsif ( @$operator[$i] eq "=" ) {
-                    $attr .= " \@attr 4=107 ";    #Number Exact match
-                }
-                elsif ( @$operator[$i] eq "start" ) {
-                    $attr .= " \@attr 3=2 \@attr 4=1 \@attr 5=1 "
-                      ;    #Firstinfield Phrase, Right truncated
-                }
-                elsif ( @$operator[$i] eq "exact" ) {
-                    $attr .= " \@attr 4=1  \@attr 5=100 \@attr 6=3 "
-                      ; ##Phrase, No truncation,all of subfield field must match
-                }
-                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]."\"";
-                $q2 .=$attr;
-                $dosearch=1;
-                ++$attr_cnt;
-            }#if value
-        }
-        ##Add how many queries generated
-        if (defined $query && $query=~/\S+/){
-          $query= $and x $attr_cnt . $query . (defined $q2 ? $q2 : '');
-        } else {
-          $query= $q2;
-        }
-        ## Adding order
-        #$query=' @or  @attr 7=2 @attr 1=Heading 0 @or  @attr 7=1 @attr 1=Heading 1'.$query if ($sortby eq "HeadingDsc");
-        my $orderstring;
-        if ($sortby eq 'HeadingAsc') {
-            $orderstring = '@attr 7=1 @attr 1=Heading 0';
-        } elsif ($sortby eq 'HeadingDsc') {
-            $orderstring = '@attr 7=2 @attr 1=Heading 0';
-        } elsif ($sortby eq 'AuthidAsc') {
-            $orderstring = '@attr 7=1 @attr 1=Local-Number 0';
-        } elsif ($sortby eq 'AuthidDsc') {
-            $orderstring = '@attr 7=2 @attr 1=Local-Number 0';
-        }
+
+        $qpquery .= " #$sortby";
+
+        $QParser->parse( $qpquery );
+        $query = $QParser->target_syntax('authorityserver');
+    } else {
         $query=($query?$query:"\@attr 1=_ALLRECORDS \@attr 2=103 ''");
         $query="\@or $orderstring $query" if $orderstring;
+    }
 
-        $offset=0 unless $offset;
-        my $counter = $offset;
-        $length=10 unless $length;
-        my @oAuth;
-        my $i;
-        $oAuth[0]=C4::Context->Zconn("authorityserver" , 1);
-        my $Anewq= new ZOOM::Query::PQF($query,$oAuth[0]);
-        my $oAResult;
-        $oAResult= $oAuth[0]->search($Anewq) ; 
-        while (($i = ZOOM::event(\@oAuth)) != 0) {
-            my $ev = $oAuth[$i-1]->last_event();
-            last if $ev == ZOOM::Event::ZEND;
-        }
-        my($error, $errmsg, $addinfo, $diagset) = $oAuth[0]->error_x();
-        if ($error) {
-            warn  "oAuth error: $errmsg ($error) $addinfo $diagset\n";
-            goto NOLUCK;
-        }
-        
-        my $nbresults;
-        $nbresults=$oAResult->size();
-        my $nremains=$nbresults;    
-        my @result = ();
-        my @finalresult = ();
-        
-        if ($nbresults>0){
+    $offset=0 unless $offset;
+    my $counter = $offset;
+    $length=10 unless $length;
+    my @oAuth;
+    my $i;
+    $oAuth[0]=C4::Context->Zconn("authorityserver" , 1);
+    my $Anewq= new ZOOM::Query::PQF($query,$oAuth[0]);
+    my $oAResult;
+    $oAResult= $oAuth[0]->search($Anewq) ;
+    while (($i = ZOOM::event(\@oAuth)) != 0) {
+        my $ev = $oAuth[$i-1]->last_event();
+        last if $ev == ZOOM::Event::ZEND;
+    }
+    my($error, $errmsg, $addinfo, $diagset) = $oAuth[0]->error_x();
+    if ($error) {
+        warn  "oAuth error: $errmsg ($error) $addinfo $diagset\n";
+        goto NOLUCK;
+    }
+
+    my $nbresults;
+    $nbresults=$oAResult->size();
+    my $nremains=$nbresults;
+    my @result = ();
+    my @finalresult = ();
+
+    if ($nbresults>0){
+
+    ##Find authid and linkid fields
+    ##we may be searching multiple authoritytypes.
+    ## FIXME this assumes that all authid and linkid fields are the same for all authority types
+    # my ($authidfield,$authidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.authid",$authtypecode[0]);
+    # my ($linkidfield,$linkidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.linkid",$authtypecode[0]);
+        while (($counter < $nbresults) && ($counter < ($offset + $length))) {
         
-        ##Find authid and linkid fields
-        ##we may be searching multiple authoritytypes.
-        ## FIXME this assumes that all authid and linkid fields are the same for all authority types
-        # my ($authidfield,$authidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.authid",$authtypecode[0]);
-        # my ($linkidfield,$linkidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.linkid",$authtypecode[0]);
-            while (($counter < $nbresults) && ($counter < ($offset + $length))) {
-            
-            ##Here we have to extract MARC record and $authid from ZEBRA AUTHORITIES
-            my $rec=$oAResult->record($counter);
-            my $marcdata=$rec->raw();
-            my $authrecord;
-            my $separator=C4::Context->preference('authoritysep');
-            $authrecord = MARC::File::USMARC::decode($marcdata);
-            my $authid=$authrecord->field('001')->data(); 
-            my %newline;
-            $newline{authid} = $authid;
-            if ( !$skipmetadata ) {
-                my $summary =
-                  BuildSummary( $authrecord, $authid, $authtypecode );
-                my $query_auth_tag =
+        ##Here we have to extract MARC record and $authid from ZEBRA AUTHORITIES
+        my $rec=$oAResult->record($counter);
+        my $marcdata=$rec->raw();
+        my $authrecord;
+        my $separator=C4::Context->preference('authoritysep');
+        $authrecord = MARC::File::USMARC::decode($marcdata);
+        my $authid=$authrecord->field('001')->data();
+        my %newline;
+        $newline{authid} = $authid;
+        if ( !$skipmetadata ) {
+            my $summary =
+              BuildSummary( $authrecord, $authid, $authtypecode );
+            my $query_auth_tag =
 "SELECT auth_tag_to_report FROM auth_types WHERE authtypecode=?";
-                my $sth = $dbh->prepare($query_auth_tag);
-                $sth->execute($authtypecode);
-                my $auth_tag_to_report = $sth->fetchrow;
-                my $reported_tag;
-                my $mainentry = $authrecord->field($auth_tag_to_report);
-                if ($mainentry) {
-
-                    foreach ( $mainentry->subfields() ) {
-                        $reported_tag .= '$' . $_->[0] . $_->[1];
-                    }
+            my $sth = $dbh->prepare($query_auth_tag);
+            $sth->execute($authtypecode);
+            my $auth_tag_to_report = $sth->fetchrow;
+            my $reported_tag;
+            my $mainentry = $authrecord->field($auth_tag_to_report);
+            if ($mainentry) {
+
+                foreach ( $mainentry->subfields() ) {
+                    $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;
             }
-            $counter++;
-            push @finalresult, \%newline;
-            }## while counter
-            ###
-            if (! $skipmetadata) {
-                for (my $z=0; $z<@finalresult; $z++){
-                    my  $count=CountUsage($finalresult[$z]{authid});
-                    $finalresult[$z]{used}=$count;
-                }# all $z's
+            my $thisauthtype = GetAuthType(GetAuthTypeCode($authid));
+            unless (defined $thisauthtype) {
+                $thisauthtype = GetAuthType($authtypecode) if $authtypecode;
             }
+            $newline{authtype}     = defined($thisauthtype) ?
+                                        $thisauthtype->{'authtypetext'} : '';
+            $newline{summary}      = $summary;
+            $newline{even}         = $counter % 2;
+            $newline{reported_tag} = $reported_tag;
+        }
+        $counter++;
+        push @finalresult, \%newline;
+        }## while counter
+        ###
+        if (! $skipmetadata) {
+            for (my $z=0; $z<@finalresult; $z++){
+                my  $count=CountUsage($finalresult[$z]{authid});
+                $finalresult[$z]{used}=$count;
+            }# all $z's
+        }
 
-        }## if nbresult
-        NOLUCK:
-        $oAResult->destroy();
-        # $oAuth[0]->destroy();
-        
-        return (\@finalresult, $nbresults);
-    }
+    }## if nbresult
+    NOLUCK:
+    $oAResult->destroy();
+    # $oAuth[0]->destroy();
+
+    return (\@finalresult, $nbresults);
 }
 
 =head2 CountUsage 
@@ -396,15 +328,9 @@ counts Usage of Authid in bibliorecords.
 
 sub CountUsage {
     my ($authid) = @_;
-    if (C4::Context->preference('NoZebra')) {
-        # Read the index Koha-Auth-Number for this authid and count the lines
-        my $result = C4::Search::NZanalyse("an=$authid");
-        my @tab = split /;/,$result;
-        return scalar @tab;
-    } else {
         ### ZOOM search here
         my $query;
-        $query= "an=".$authid;
+        $query= "an:".$authid;
                my ($err,$res,$result) = C4::Search::SimpleSearch($query,0,10);
         if ($err) {
             warn "Error: $err from search $query";
@@ -412,7 +338,6 @@ sub CountUsage {
         }
 
         return $result;
-    }
 }
 
 =head2 CountUsageChildren 
@@ -454,9 +379,9 @@ Get the record and tries to guess the adequate authtypecode from its content.
 =cut
 
 sub GuessAuthTypeCode {
-    my ($record) = @_;
+    my ($record, $heading_fields) = @_;
     return unless defined $record;
-my $heading_fields = {
+    $heading_fields //= {
     "MARC21"=>{
         '100'=>{authtypecode=>'PERSO_NAME'},
         '110'=>{authtypecode=>'CORPO_NAME'},
@@ -595,7 +520,7 @@ sub GetTagsLabels {
         $res->{$tag}->{repeatable} = $repeatable;
   }
   $sth=      $dbh->prepare(
-"SELECT tagfield,tagsubfield,liblibrarian,libopac,tab, mandatory, repeatable,authorised_value,frameworkcode as authtypecode,value_builder,kohafield,seealso,hidden,isurl 
+"SELECT tagfield,tagsubfield,liblibrarian,libopac,tab, mandatory, repeatable,authorised_value,frameworkcode as authtypecode,value_builder,kohafield,seealso,hidden,isurl,defaultvalue
 FROM auth_subfield_structure 
 WHERE authtypecode=? 
 ORDER BY tagfield,tagsubfield"
@@ -610,12 +535,13 @@ ORDER BY tagfield,tagsubfield"
     my $hidden;
     my $isurl;
     my $link;
+    my $defaultvalue;
 
     while (
         ( $tag,         $subfield,   $liblibrarian,   , $libopac,      $tab,
         $mandatory,     $repeatable, $authorised_value, $authtypecode,
         $value_builder, $kohafield,  $seealso,          $hidden,
-        $isurl,            $link )
+        $isurl,         $defaultvalue, $link )
         = $sth->fetchrow
       )
     {
@@ -631,6 +557,7 @@ ORDER BY tagfield,tagsubfield"
         $res->{$tag}->{$subfield}->{hidden}           = $hidden;
         $res->{$tag}->{$subfield}->{isurl}            = $isurl;
         $res->{$tag}->{$subfield}->{link}            = $link;
+        $res->{$tag}->{$subfield}->{defaultvalue}     = $defaultvalue;
     }
     return $res;
 }
@@ -704,17 +631,18 @@ sub AddAuthority {
 
   if ($format eq "UNIMARCAUTH") {
         $record->leader("     nx  j22             ") unless ($record->leader());
-        my $date=POSIX::strftime("%Y%m%d",localtime);    
+        my $date=POSIX::strftime("%Y%m%d",localtime);
+       my $defaultfield100 = C4::Context->preference('UNIMARCAuthorityField100');
     if (my $string=$record->subfield('100',"a")){
        $string=~s/fre50/frey50/;
        $record->field('100')->update('a'=>$string);
     }
     elsif ($record->field('100')){
-          $record->field('100')->update('a'=>$date."afrey50      ba0");
+          $record->field('100')->update('a'=>$date.$defaultfield100);
     } else {      
         $record->append_fields(
         MARC::Field->new('100',' ',' '
-            ,'a'=>$date."afrey50      ba0")
+            ,'a'=>$date.$defaultfield100)
         );
     }      
   }
@@ -856,6 +784,7 @@ Returns MARC::Record of the authority passed in parameter.
 sub GetAuthority {
     my ($authid)=@_;
     my $authority = Koha::Authority->get_from_authid($authid);
+    return unless $authority;
     return ($authority->record);
 }
 
@@ -907,11 +836,19 @@ sub FindDuplicateAuthority {
     $sth->finish;
 #     warn "record :".$record->as_formatted."  auth_tag_to_report :$auth_tag_to_report";
     # build a request for SearchAuthorities
-    my $query='at='.$authtypecode.' ';
+    my $QParser;
+    $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser'));
+    my $op;
+    if ($QParser) {
+        $op = '&&';
+    } else {
+        $op = 'and';
+    }
+    my $query='at:'.$authtypecode.' ';
     my $filtervalues=qr([\001-\040\!\'\"\`\#\$\%\&\*\+,\-\./:;<=>\?\@\(\)\{\[\]\}_\|\~]);
     if ($record->field($auth_tag_to_report)) {
       foreach ($record->field($auth_tag_to_report)->subfields()) {
-        $_->[1]=~s/$filtervalues/ /g; $query.= " and he,wrdl=\"".$_->[1]."\"" if ($_->[0]=~/[A-z]/);
+        $_->[1]=~s/$filtervalues/ /g; $query.= " $op he:\"".$_->[1]."\"" if ($_->[0]=~/[A-z]/);
       }
     }
     my ($error, $results, $total_hits) = C4::Search::SimpleSearch( $query, 0, 1, [ "authorityserver" ] );
@@ -959,6 +896,11 @@ sub BuildSummary {
         'i' => 'subfi',
         't' => 'parent'
     );
+    my %unimarc_relation_from_code = (
+        g => 'broader',
+        h => 'narrower',
+        a => 'seealso',
+    );
     my %thesaurus;
     $thesaurus{'1'}="Peuples";
     $thesaurus{'2'}="Anthroponymes";
@@ -1013,7 +955,11 @@ sub BuildSummary {
 # construct UNIMARC summary, that is quite different from MARC21 one
 # accepted form
         foreach my $field ($record->field('2..')) {
-            push @authorized, { heading => $field->as_string('abcdefghijlmnopqrstuvwxyz'), field => $field->tag() };
+            push @authorized, {
+                heading => $field->as_string('abcdefghijlmnopqrstuvwxyz'),
+                hemain  => $field->subfield('a'),
+                field   => $field->tag(),
+            };
         }
 # rejected form(s)
         foreach my $field ($record->field('3..')) {
@@ -1021,41 +967,36 @@ sub BuildSummary {
         }
         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() };
+            push @seefrom, {
+                heading => $thesaurus . $field->as_string('abcdefghijlmnopqrstuvwxyz'),
+                hemain  => $field->subfield('a'),
+                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, {
-                    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')
-                };
+
+        # see :
+        @seealso = map {
+            my $type = $unimarc_relation_from_code{$_->subfield('5') || 'a'};
+            my $heading = $_->as_string('abcdefgjxyz');
+            {
+                field   => $_->tag,
+                type    => $type,
+                heading => $heading,
+                hemain  => $_->subfield('a'),
+                search  => $heading,
+                authid  => $_->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'), direction => 'ltr', field => $field->tag() };
-        }
+        } $record->field('5..');
+
+        # Other forms
+        @otherscript = map { {
+            lang      => length ($_->subfield('8')) == 6 ? substr ($_->subfield('8'), 3, 3) : $_->subfield('8') || '',
+            term      => $_->subfield('a') . ($_->subfield('b') ? ', ' . $_->subfield('b') : ''),
+            direction => 'ltr',
+            field     => $_->tag,
+        } } $record->field('7..');
+
     } else {
 # construct MARC21 summary
 # FIXME - looping over 1XX is questionable
@@ -1093,9 +1034,17 @@ sub BuildSummary {
                 $subfields_to_report = 'vxyz';
             }
             if ($subfields_to_report) {
-                push @authorized, { heading => $field->as_string($subfields_to_report), field => $tag };
+                push @authorized, {
+                    heading => $field->as_string($subfields_to_report),
+                    hemain  => $field->subfield( substr($subfields_to_report, 0, 1) ),
+                    field   => $tag,
+                };
             } else {
-                push @authorized, { heading => $field->as_string(), field => $tag };
+                push @authorized, {
+                    heading => $field->as_string(),
+                    hemain  => $field->subfield('a'),
+                    field   => $tag,
+                };
             }
         }
         foreach my $field ($record->field('4..')) { #See From
@@ -1106,9 +1055,19 @@ sub BuildSummary {
                 $type = 'earlier' if $type && $type ne 'n';
             }
             if ($type eq 'subfi') {
-                push @seefrom, { heading => $field->as_string($marc21subfields), type => ($field->subfield('i') || ''), field => $field->tag() };
+                push @seefrom, {
+                    heading => $field->as_string($marc21subfields),
+                    hemain  => $field->subfield( substr($marc21subfields, 0, 1) ),
+                    type    => ($field->subfield('i') || ''),
+                    field   => $field->tag(),
+                };
             } else {
-                push @seefrom, { heading => $field->as_string($marc21subfields), type => $type, field => $field->tag() };
+                push @seefrom, {
+                    heading => $field->as_string($marc21subfields),
+                    hemain  => $field->subfield( substr($marc21subfields, 0, 1) ),
+                    type    => $type,
+                    field   => $field->tag(),
+                };
             }
         }
         foreach my $field ($record->field('5..')) { #See Also
@@ -1121,18 +1080,20 @@ sub BuildSummary {
             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') || ''
+                    hemain  => $field->subfield( substr($marc21subfields, 0, 1) ),
+                    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') || ''
+                    hemain  => $field->subfield( substr($marc21subfields, 0, 1) ),
+                    type    => $type,
+                    field   => $field->tag(),
+                    search  => $field->as_string($marc21subfields) || '',
+                    authid  => $field->subfield('9') || ''
                 };
             }
         }
@@ -1160,6 +1121,7 @@ sub BuildSummary {
         }
     }
     $summary{mainentry} = $authorized[0]->{heading};
+    $summary{mainmainentry} = $authorized[0]->{hemain};
     $summary{authorized} = \@authorized;
     $summary{notes} = \@notes;
     $summary{seefrom} = \@seefrom;
@@ -1186,6 +1148,7 @@ sub GetAuthorizedHeading {
         return unless $args->{authid};
         $record = GetAuthority($args->{authid});
     }
+    return unless (ref $record eq 'MARC::Record');
     if (C4::Context->preference('marcflavour') eq 'UNIMARC') {
 # construct UNIMARC summary, that is quite different from MARC21 one
 # accepted form
@@ -1476,46 +1439,30 @@ sub merge {
     my @reccache;
     # search all biblio tags using this authority.
     #Getting marcbiblios impacted by the change.
-    if (C4::Context->preference('NoZebra')) {
-        #nozebra way    
-        my $dbh=C4::Context->dbh;
-        my $rq=$dbh->prepare(qq(SELECT biblionumbers from nozebra where indexname="an" and server="biblioserver" and value="$mergefrom" ));
-        $rq->execute;
-        while (my $biblionumbers=$rq->fetchrow){
-            my @biblionumbers=split /;/,$biblionumbers;
-            foreach (@biblionumbers) {
-                if ($_=~/(\d+),.*/) {
-                    my $marc=GetMarcBiblio($1);
-                    push @reccache,$marc;
-                }
-            }
-        }
-    } else {
-        #zebra connection  
-        my $oConnection=C4::Context->Zconn("biblioserver",0);
-        # 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 ));
-        my $count = 0;
-        if  ($oResult) {
-            $count=$oResult->size();
-        }
-        my $z=0;
-        while ( $z<$count ) {
-            my $rec;
-            $rec=$oResult->record($z);
-            my $marcdata = $rec->raw();
-            my $marcrecordzebra= MARC::Record->new_from_usmarc($marcdata);
-            my ( $biblionumbertagfield, $biblionumbertagsubfield ) = &GetMarcFromKohaField( "biblio.biblionumber", '' );
-            my $i = ($biblionumbertagfield < 10) ? $marcrecordzebra->field($biblionumbertagfield)->data : $marcrecordzebra->subfield($biblionumbertagfield, $biblionumbertagsubfield);
-            my $marcrecorddb=GetMarcBiblio($i);
-            push @reccache, $marcrecorddb;
-            $z++;
-        }
-        $oResult->destroy();
+    #zebra connection
+    my $oConnection=C4::Context->Zconn("biblioserver",0);
+    # 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 ));
+    my $count = 0;
+    if  ($oResult) {
+        $count=$oResult->size();
+    }
+    my $z=0;
+    while ( $z<$count ) {
+        my $rec;
+        $rec=$oResult->record($z);
+        my $marcdata = $rec->raw();
+        my $marcrecordzebra= MARC::Record->new_from_usmarc($marcdata);
+        my ( $biblionumbertagfield, $biblionumbertagsubfield ) = &GetMarcFromKohaField( "biblio.biblionumber", '' );
+        my $i = ($biblionumbertagfield < 10) ? $marcrecordzebra->field($biblionumbertagfield)->data : $marcrecordzebra->subfield($biblionumbertagfield, $biblionumbertagsubfield);
+        my $marcrecorddb=GetMarcBiblio($i);
+        push @reccache, $marcrecorddb;
+        $z++;
     }
+    $oResult->destroy();
     #warn scalar(@reccache)." biblios to update";
     # Get All candidate Tags for the change 
     # (This will reduce the search scope in marc records).