X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=C4%2FAuthoritiesMarc.pm;h=95fe33a732ccb6d4f8858b9bd4bc3f5d3e029243;hb=5d6c092921919526ade501facb1220f8a108a08f;hp=b6e3690bbfbb01a62e92ca09aa4ab36072e1913b;hpb=9b8a5274732edd0bbcf3dd80b82c00b182a292da;p=koha_fer diff --git a/C4/AuthoritiesMarc.pm b/C4/AuthoritiesMarc.pm index b6e3690bbf..95fe33a732 100644 --- a/C4/AuthoritiesMarc.pm +++ b/C4/AuthoritiesMarc.pm @@ -109,283 +109,221 @@ 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 4=109 @attr 1=Local-Number 0'; - } elsif ($sortby eq 'AuthidDsc') { - $orderstring = '@attr 7=2 @attr 4=109 @attr 1=Local-Number 0'; - } + + $qpquery .= " #$sortby" unless $sortby eq ''; + + $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 $separator=C4::Context->preference('AuthoritySeparator'); + my $authrecord = C4::Search::new_record_from_zebra( + 'authorityserver', + $rec->raw() + ); + + if ( !defined $authrecord or !defined $authrecord->field('001') ) { + $counter++; + next; + } + + my $authid=$authrecord->field('001')->data(); + my %newline; + $newline{authid} = $authid; + if ( !$skipmetadata ) { + 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 $thisauthtype = GetAuthType(GetAuthTypeCode($authid)); - unless (defined $thisauthtype) { - $thisauthtype = GetAuthType($authtypecode) if $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]; } - $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 + my $thisauthtypecode = GetAuthTypeCode($authid); + my $thisauthtype = GetAuthType($thisauthtypecode); + unless (defined $thisauthtype) { + $thisauthtypecode = $authtypecode; + $thisauthtype = GetAuthType($authtypecode); } + my $summary = BuildSummary( $authrecord, $authid, $thisauthtypecode ); - }## if nbresult - NOLUCK: - $oAResult->destroy(); - # $oAuth[0]->destroy(); - - return (\@finalresult, $nbresults); - } + $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); } =head2 CountUsage @@ -398,15 +336,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"; @@ -414,7 +346,6 @@ sub CountUsage { } return $result; - } } =head2 CountUsageChildren @@ -456,9 +387,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'}, @@ -597,7 +528,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" @@ -612,12 +543,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 ) { @@ -633,6 +565,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; } @@ -814,7 +747,7 @@ sub ModAuthority { "VALUES (?,?)"; $dbh->do($sqlinsert,undef,($authid,0)); } - logaction( "AUTHORITIES", "MODIFY", $authid, "BEFORE=>" . $oldrecord->as_formatted ) if C4::Context->preference("AuthoritiesLog"); + logaction( "AUTHORITIES", "MODIFY", $authid, "authority BEFORE=>" . $oldrecord->as_formatted ) if C4::Context->preference("AuthoritiesLog"); return $authid; } @@ -911,18 +844,29 @@ 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]/); - } + foreach ($record->field($auth_tag_to_report)->subfields()) { + $_->[1]=~s/$filtervalues/ /g; $query.= " $op he:\"".$_->[1]."\"" if ($_->[0]=~/[A-z]/); + } } my ($error, $results, $total_hits) = C4::Search::SimpleSearch( $query, 0, 1, [ "authorityserver" ] ); # there is at least 1 result => return the 1st one if (!defined $error && @{$results} ) { - my $marcrecord = MARC::File::USMARC::decode($results->[0]); - return $marcrecord->field('001')->data,BuildSummary($marcrecord,$marcrecord->field('001')->data,$authtypecode); + my $marcrecord = C4::Search::new_record_from_zebra( + 'authorityserver', + $results->[0] + ); + return $marcrecord->field('001')->data,BuildSummary($marcrecord,$marcrecord->field('001')->data,$authtypecode); } # no result, returns nothing return; @@ -945,12 +889,18 @@ sub BuildSummary { my ($record,$authid,$authtypecode)=@_; my $dbh=C4::Context->dbh; my %summary; + my $summary_template; # handle $authtypecode is NULL or eq "" if ($authtypecode) { my $authref = GetAuthType($authtypecode); $summary{authtypecode} = $authref->{authtypecode}; $summary{type} = $authref->{authtypetext}; - $summary{summary} = $authref->{summary}; + $summary_template = $authref->{summary}; + # for MARC21, the authority type summary displays a label meant for + # display + if (C4::Context->preference('marcflavour') ne 'UNIMARC') { + $summary{summary} = $authref->{summary}; + } } my $marc21subfields = 'abcdfghjklmnopqrstuvxyz68'; my %marc21controlrefs = ( 'a' => 'earlier', @@ -983,14 +933,14 @@ sub BuildSummary { # suit the MARC21 version, so for now the "templating" # feature will be enabled only for UNIMARC for backwards # compatibility. - if ($summary{summary} and C4::Context->preference('marcflavour') eq 'UNIMARC') { + if ($summary_template and C4::Context->preference('marcflavour') eq 'UNIMARC') { my @fields = $record->fields(); # $reported_tag = '$9'.$result[$counter]; - my @stringssummary; + my @repets; foreach my $field (@fields) { my $tag = $field->tag(); my $tagvalue = $field->as_string(); - my $localsummary= $summary{summary}; + my $localsummary= $summary_template; $localsummary =~ s/\[(.?.?.?.?)$tag\*(.*?)\]/$1$tagvalue$2\[$1$tag$2\]/g; if ($tag<10) { if ($tag eq '001') { @@ -1005,13 +955,13 @@ sub BuildSummary { $localsummary =~ s/\[(.?.?.?.?)$tagsubf(.*?)\]/$1$subfieldvalue$2\[$1$tagsubf$2\]/g; } } - push @stringssummary, $localsummary if ($localsummary ne $summary{summary}); + if ($localsummary ne $summary_template) { + $localsummary =~ s/\[(.*?)\]//g; + $localsummary =~ s/\n/
/g; + push @repets, $localsummary; + } } - my $resultstring; - $resultstring = join(" -- ",@stringssummary); - $resultstring =~ s/\[(.*?)\]//g; - $resultstring =~ s/\n/
/g; - $summary{summary} = $resultstring; + $summary{repets} = \@repets; } my @authorized; my @notes; @@ -1022,7 +972,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') // undef ), + field => $field->tag(), + }; } # rejected form(s) foreach my $field ($record->field('3..')) { @@ -1030,7 +984,12 @@ 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') // undef ), + type => 'seefrom', + field => $field->tag(), + }; } # see : @@ -1041,15 +1000,16 @@ sub BuildSummary { field => $_->tag, type => $type, heading => $heading, + hemain => ( $_->subfield('a') // undef ), search => $heading, - authid => $_->subfield('9'), + authid => ( $_->subfield('9') // undef ), } } $record->field('5..'); # Other forms @otherscript = map { { - lang => $_->subfield('8') || '', - term => $_->subfield('a'), + 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..'); @@ -1091,9 +1051,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) ) // undef ), + field => $tag, + }; } else { - push @authorized, { heading => $field->as_string(), field => $tag }; + push @authorized, { + heading => $field->as_string(), + hemain => ( $field->subfield( 'a' ) // undef ), + field => $tag, + }; } } foreach my $field ($record->field('4..')) { #See From @@ -1104,9 +1072,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 @@ -1119,18 +1097,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') || '' }; } } @@ -1158,6 +1138,7 @@ sub BuildSummary { } } $summary{mainentry} = $authorized[0]->{heading}; + $summary{mainmainentry} = $authorized[0]->{hemain}; $summary{authorized} = \@authorized; $summary{notes} = \@notes; $summary{seefrom} = \@seefrom; @@ -1184,6 +1165,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 @@ -1474,46 +1456,32 @@ 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 $marcrecordzebra = C4::Search::new_record_from_zebra( + 'biblioserver', + $oResult->record($z)->raw() + ); + 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).