X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FAuthoritiesMarc.pm;h=aef8b6c60e7481cd069495e183978d73d3c31096;hb=198bae17b1ebd42f4c1ce3b21e13b7ad7b844b64;hp=5a4021b37053f492dc5ad82b236e8b31d8a8270b;hpb=a481fad4b7e84e1571fb2750ee99d1edf234b796;p=koha.git diff --git a/C4/AuthoritiesMarc.pm b/C4/AuthoritiesMarc.pm index 5a4021b370..aef8b6c60e 100644 --- a/C4/AuthoritiesMarc.pm +++ b/C4/AuthoritiesMarc.pm @@ -17,44 +17,66 @@ package C4::AuthoritiesMarc; # Suite 330, Boston, MA 02111-1307 USA use strict; -require Exporter; use C4::Context; use C4::Koha; use MARC::Record; use C4::Biblio; use C4::Search; -#use ZOOM; +use C4::AuthoritiesMarc::MARC21; +use C4::AuthoritiesMarc::UNIMARC; +use C4::Charset; +use C4::Debug; + use vars qw($VERSION @ISA @EXPORT); -# set the version for version checking -$VERSION = 0.01; - -@ISA = qw(Exporter); -@EXPORT = qw( - &AUTHgettagslib - &AUTHfindsubfield - &AUTHfind_authtypecode - - &AUTHaddauthority - &AUTHmodauthority - &AUTHdelauthority - &AUTHaddsubfield - &AUTHgetauthority - &AUTHfind_marc_from_kohafield - &AUTHgetauth_type - &AUTHcount_usage - &getsummary - &authoritysearch - &XMLgetauthority +BEGIN { + # set the version for version checking + $VERSION = 3.01; + + require Exporter; + @ISA = qw(Exporter); + @EXPORT = qw( + &GetTagsLabels + &GetAuthType + &GetAuthTypeCode + &GetAuthMARCFromKohaField + &AUTHhtml2marc + + &AddAuthority + &ModAuthority + &DelAuthority + &GetAuthority + &GetAuthorityXML + + &CountUsage + &CountUsageChildren + &SearchAuthorities + + &BuildSummary + &BuildUnimarcHierarchies + &BuildUnimarcHierarchy - &AUTHhtml2marc - &BuildUnimarcHierarchies - &BuildUnimarcHierarchy - &merge - &FindDuplicate - ); - -sub AUTHfind_marc_from_kohafield { + &merge + &FindDuplicateAuthority + ); +} + +=head2 GetAuthMARCFromKohaField + +=over 4 + +( $tag, $subfield ) = &GetAuthMARCFromKohaField ($kohafield,$authtypecode); +returns tag and subfield linked to kohafield + +Comment : +Suppose Kohafield is only linked to ONE subfield + +=back + +=cut + +sub GetAuthMARCFromKohaField { +#AUTHfind_marc_from_kohafield my ( $kohafield,$authtypecode ) = @_; my $dbh=C4::Context->dbh; return 0, 0 unless $kohafield; @@ -66,241 +88,355 @@ sub AUTHfind_marc_from_kohafield { return ($tagfield,$tagsubfield); } -sub authoritysearch { - my ($tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode,$sortby) = @_; - my $dbh=C4::Context->dbh; - 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 - my $n=0; - my @authtypecode; - my @auths=split / /,$authtypecode ; - foreach my $auth (@auths){ - $query .=" \@attr 1=Authority/format-id \@attr 5=100 ".$auth; ##No truncation on authtype - push @authtypecode ,$auth; - $n++; - } - if ($n>1){ - $query= "\@or ".$query; - } - - my $dosearch; - my $and; - my $q2; - for(my $i = 0 ; $i <= $#{$value} ; $i++) - { - if (@$value[$i]){ - ##If mainentry search $a tag - if (@$tags[$i] eq "mainmainentry") { - $attr =" \@attr 1=Heading "; - }elsif (@$tags[$i] eq "mainentry") { - $attr =" \@attr 1=Heading-Entity "; - }else{ - $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 4=1 \@attr 5=1 ";#Phrase, Right truncated - } else { - $attr .=" \@attr 5=1 ";## Word list, right truncated, anywhere - } - $and .=" \@and " ; - $attr =$attr."\"".@$value[$i]."\""; - $q2 .=$attr; - $dosearch=1; - }#if value - } - ##Add how many queries generated - $query= $and.$query.$q2; - $query=' @or @attr 7=1 @attr 1=Heading 0 '.$query if ($sortby eq "HeadingAsc"); - $query=' @or @attr 7=2 @attr 1=Heading 0 '.$query if ($sortby eq "HeadingDsc"); - warn $query; - - $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]); - # $Anewq->sortby("1=Heading i< 1=Heading-Entity i< "); - # $Anewq->sortby("1=Heading i< 1=Heading-Entity i< "); - my $oAResult; - $oAResult= $oAuth[0]->search($Anewq) ; - while (($i = ZOOM::event(\@oAuth)) != 0) { - my $ev = $oAuth[$i-1]->last_event(); - # warn("Authority ", $i-1, ": event $ev (", ZOOM::event_str($ev), ")\n"); - 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 = (); +=head2 SearchAuthorities - if ($nbresults>0){ +=over 4 - ##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)=AUTHfind_marc_from_kohafield($dbh,"auth_header.authid",$authtypecode[0]); - # my ($linkidfield,$linkidsubfield)=AUTHfind_marc_from_kohafield($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 $linkid; - my @linkids; - my $separator=C4::Context->preference('authoritysep'); - my $linksummary=" ".$separator; - - $authrecord = MARC::File::USMARC::decode($marcdata); - - my $authid=$authrecord->field('001')->data(); - # if ($authrecord->field($linkidfield)){ - # my @fields=$authrecord->field($linkidfield); - # - # # foreach my $field (@fields){ - # # # $linkid=$field->subfield($linkidsubfield) ; - # # # if ($linkid){ ##There is a linked record add fields to produce summary - # # # my $linktype=AUTHfind_authtypecode($dbh,$linkid); - # # # my $linkrecord=AUTHgetauthority($dbh,$linkid); - # # # $linksummary.="
    ".getsummary($dbh,$linkrecord,$linkid,$linktype).".".$separator; - # # # } - # # } - # }# - - my $summary=getsummary($authrecord,$authid,$authtypecode); - # $summary="".$summary."." if ($intranet); - # $summary="".$summary."." if ($intranet); - # if ($linkid && $linksummary ne " ".$separator){ - # $summary="".$summary."".$linksummary; - # } - 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{summary} = $summary; - $newline{authid} = $authid; - # $newline{linkid} = $linkid; - # $newline{reported_tag} = $reported_tag; - # $newline{used} =0; - # $newline{biblio_fields} = $tags_using_authtype; - $newline{even} = $counter % 2; - $counter++; - push @finalresult, \%newline; - }## while counter - ### - for (my $z=0; $z<@finalresult; $z++){ - my $count=AUTHcount_usage($finalresult[$z]{authid}); - $finalresult[$z]{used}=$count; - }# all $z's - - }## if nbresult -NOLUCK: -# $oAResult->destroy(); -# $oAuth[0]->destroy(); - - return (\@finalresult, $nbresults); -} +(\@finalresult, $nbresults)= &SearchAuthorities($tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode,$sortby) +returns ref to array result and count of results returned -# Creates the SQL Request +=back -sub create_request { - my ($tags, $and_or, $operator, $value) = @_; - my $dbh=C4::Context->dbh; +=cut - my $sql_tables; # will contain marc_subfield_table as m1,... - my $sql_where1; # will contain the "true" where - my $sql_where2 = "("; # will contain m1.authid=m2.authid - my $nb_active=0; # will contain the number of "active" entries. and entry is active is a value is provided. - my $nb_table=1; # will contain the number of table. ++ on each entry EXCEPT when an OR is provided. - - for(my $i=0; $i<=@$value;$i++) { - if (@$value[$i]) { - $nb_active++; - if ($nb_active==1) { - $sql_tables = "auth_subfield_table as m$nb_table,"; - $sql_where1 .= "( m$nb_table.subfieldvalue like '@$value[$i]' "; - if (@$tags[$i]) { - $sql_where1 .=" and concat(m$nb_table.tag,m$nb_table.subfieldcode) IN (@$tags[$i])"; - } - $sql_where1.=")"; +sub SearchAuthorities { + my ($tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode,$sortby) = @_; +# warn "CALL : $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 @auths=split / /,$authtypecode ; + foreach my $auth (@auths){ + $query .="AND auth_type= $auth "; + } + $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 + } + # + # 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; + } + # 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++; + } + } + # 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; + } + return (\@finalresult, $numbers); } else { - $nb_table++; - $sql_tables .= "auth_subfield_table as m$nb_table,"; - $sql_where1 .= "@$and_or[$i] (m$nb_table.subfieldvalue like '@$value[$i]' "; - if (@$tags[$i]) { - $sql_where1 .=" and concat(m$nb_table.tag,m$nb_table.subfieldcode) IN (@$tags[$i])"; - } - $sql_where1.=")"; - $sql_where2.="m1.authid=m$nb_table.authid and "; + 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 + my $n=0; + my @authtypecode; + my @auths=split / /,$authtypecode ; + my @queries; + foreach my $auth (@auths){ + push @queries, " \@attr 1=authtype \@attr 5=100 ".$auth; ##No truncation on authtype + push @authtypecode ,$auth; + $n++; + } + if ($n>1){ + while ($n>1){$query= "\@or ".$query;$n--;} + } + + my $dosearch; + my $and=" \@and " ; + for(my $i = 0 ; $i <= $#{$value} ; $i++) + { + if (@$value[$i]){ + ##If mainentry search $a tag + if (@$tags[$i] eq "mainmainentry") { + + $attr =" \@attr 1=Heading-Main "; +# $attr =" \@attr 1=Heading "; + + }elsif (@$tags[$i] eq "mainentry") { + $attr =" \@attr 1=Heading "; + }else{ + $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 + } else { + $attr .=" \@attr 5=1 \@attr 4=6 ";## Word list, right truncated, anywhere + } + $attr =$attr."\"".@$value[$i]."\""; + push @queries, "$attr"; + $dosearch=1; + }#if value + } + ##Add how many queries generated + my $query; + foreach my $query_part (@queries){ + $query=($query?$and.$query_part.$query:$query_part); + } + ## 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= ($sortby eq "HeadingAsc"? + '@attr 7=1 @attr 1=Heading 0' + : + $sortby eq "HeadingDsc"? + '@attr 7=2 @attr 1=Heading 0' + :'' + ); + $query=($dosearch?"\@or $orderstring $query":"\@or ".($query?"$and $query":"")." \@attr 1=_ALLRECORDS \@attr 2=103 '' $orderstring "); + $debug && warn $query; + + $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))) { + + ##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 $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 %newline; + $newline{summary} = $summary; + $newline{authid} = $authid; + $newline{even} = $counter % 2; + $newline{reported_tag} = $reported_tag; + $counter++; + push @finalresult, \%newline; + }## while counter + ### + 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($sql_where2 ne "(") # some datas added to sql_where2, processing - { - $sql_where2 = substr($sql_where2, 0, (length($sql_where2)-5)); # deletes the trailing ' and ' - $sql_where2 .= ")"; - } - else # no sql_where2 statement, deleting '(' - { - $sql_where2 = ""; +=head2 CountUsage + +=over 4 + +$count= &CountUsage($authid) +counts Usage of Authid in bibliorecords. + +=back + +=cut + +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 $oConnection=C4::Context->Zconn("biblioserver",1); + my $query; + $query= "an=".$authid; + my $oResult = $oConnection->search(new ZOOM::Query::CCL2RPN( $query, $oConnection )); + my $result; + while ((my $i = ZOOM::event([ $oConnection ])) != 0) { + my $ev = $oConnection->last_event(); + if ($ev == ZOOM::Event::ZEND) { + $result = $oResult->size(); + } + } + return ($result); } - chop $sql_tables; # deletes the trailing ',' - - return ($sql_tables, $sql_where1, $sql_where2); } +=head2 CountUsageChildren + +=over 4 + +$count= &CountUsageChildren($authid) +counts Usage of narrower terms of Authid in bibliorecords. + +=back -sub AUTHcount_usage { +=cut + +sub CountUsageChildren { my ($authid) = @_; - ### try ZOOM search here - my $oConnection=C4::Context->Zconn("biblioserver",1); - my $query; - $query= "an=".$authid; - - my $oResult = $oConnection->search(new ZOOM::Query::CCL2RPN( $query, $oConnection )); - my $result; - while ((my $i = ZOOM::event([ $oConnection ])) != 0) { - my $ev = $oConnection->last_event(); - if ($ev == ZOOM::Event::ZEND) { - $result = $oResult->size(); - } - } - return ($result); } +=head2 GetAuthTypeCode +=over 4 -sub AUTHfind_authtypecode { +$authtypecode= &GetAuthTypeCode($authid) +returns authtypecode of an authid + +=back + +=cut + +sub GetAuthTypeCode { +#AUTHfind_authtypecode my ($authid) = @_; my $dbh=C4::Context->dbh; my $sth = $dbh->prepare("select authtypecode from auth_header where authid=?"); $sth->execute($authid); - my ($authtypecode) = $sth->fetchrow; + my $authtypecode = $sth->fetchrow; return $authtypecode; } +=head2 GetTagsLabels + +=over 4 + +$tagslabel= &GetTagsLabels($forlibrarian,$authtypecode) +returns a ref to hashref of authorities tag and subfield structure. + +tagslabel usage : +$tagslabel->{$tag}->{$subfield}->{'attribute'} +where attribute takes values in : + lib + tab + mandatory + repeatable + authorised_value + authtypecode + value_builder + kohafield + seealso + hidden + isurl + link -sub AUTHgettagslib { +=back + +=cut + +sub GetTagsLabels { my ($forlibrarian,$authtypecode)= @_; my $dbh=C4::Context->dbh; $authtypecode="" unless $authtypecode; @@ -309,12 +445,12 @@ sub AUTHgettagslib { # check that authority exists - $sth=$dbh->prepare("select count(*) from auth_tag_structure where authtypecode=?"); + $sth=$dbh->prepare("SELECT count(*) FROM auth_tag_structure WHERE authtypecode=?"); $sth->execute($authtypecode); my ($total) = $sth->fetchrow; $authtypecode="" unless ($total >0); $sth= $dbh->prepare( -"SELECT tagfield,liblibrarian,libopac,mandatory,repeatable +"SELECT auth_tag_structure.tagfield,auth_tag_structure.liblibrarian,auth_tag_structure.libopac,auth_tag_structure.mandatory,auth_tag_structure.repeatable FROM auth_tag_structure WHERE authtypecode=? ORDER BY tagfield" @@ -330,7 +466,7 @@ sub AUTHgettagslib { $res->{$tag}->{repeatable} = $repeatable; } $sth= $dbh->prepare( -"SELECT tagfield,tagsubfield,liblibrarian,libopac,tab, mandatory, repeatable,authorised_value,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 FROM auth_subfield_structure WHERE authtypecode=? ORDER BY tagfield,tagsubfield" @@ -370,213 +506,258 @@ ORDER BY tagfield,tagsubfield" return $res; } -sub AUTHaddauthority { +=head2 AddAuthority + +=over 4 + +$authid= &AddAuthority($record, $authid,$authtypecode) +returns authid of the newly created authority + +Either Create Or Modify existing authority. + +=back + +=cut + +sub AddAuthority { # pass the MARC::Record to this function, and it will create the records in the authority table my ($record,$authid,$authtypecode) = @_; my $dbh=C4::Context->dbh; -#my $leadercode=AUTHfind_leader($dbh,$authtypecode); - my $leader=' a ';##Fixme correct leader as this one just adds utf8 to MARC21 -#substr($leader,8,1)=$leadercode; -# $record->leader($leader); -# my ($authfield,$authidsubfield)=AUTHfind_marc_from_kohafield($dbh,"auth_header.authid",$authtypecode); -# my ($authfield2,$authtypesubfield)=AUTHfind_marc_from_kohafield($dbh,"auth_header.authtypecode",$authtypecode); -# my ($linkidfield,$linkidsubfield)=AUTHfind_marc_from_kohafield($dbh,"auth_header.linkid",$authtypecode); + my $leader=' nz a22 o 4500';#Leader for incomplete MARC21 record # if authid empty => true add, find a new authid number + my $format= 'UNIMARCAUTH' if (uc(C4::Context->preference('marcflavour')) eq 'UNIMARC'); + $format= 'MARC21' if (uc(C4::Context->preference('marcflavour')) ne 'UNIMARC'); + + if ($format eq "MARC21") { + if (!$record->leader) { + $record->leader($leader); + } + if (!$record->field('003')) { + $record->insert_fields_ordered( + MARC::Field->new('003',C4::Context->preference('MARCOrgCode')) + ); + } + my $time=POSIX::strftime("%Y%m%d%H%M%S",localtime); + if (!$record->field('005')) { + $record->insert_fields_ordered( + MARC::Field->new('005',$time.".0") + ); + } + my $date=POSIX::strftime("%y%m%d",localtime); + if (!$record->field('008')) { + $record->insert_fields_ordered( + MARC::Field->new('008',$date."|||a|||||| | ||| d") + ); + } + if (!$record->field('040')) { + $record->insert_fields_ordered( + MARC::Field->new('040','','', + 'a' => C4::Context->preference('MARCOrgCode'), + 'c' => C4::Context->preference('MARCOrgCode') + ) + ); + } + } + + if (($format eq "UNIMARCAUTH") && (!$record->subfield('100','a'))){ + $record->leader(" nx j22 "); + my $date=POSIX::strftime("%Y%m%d",localtime); + if ($record->field('100')){ + $record->field('100')->update('a'=>$date."afrey50 ba0"); + } else { + $record->append_fields( + MARC::Field->new('100',' ',' ' + ,'a'=>$date."afrey50 ba0") + ); + } + } + my ($auth_type_tag, $auth_type_subfield) = get_auth_type_location($authtypecode); + if (!$authid and $format eq "MARC21") { + # only need to do this fix when modifying an existing authority + C4::AuthoritiesMarc::MARC21::fix_marc21_auth_type_location($record, $auth_type_tag, $auth_type_subfield); + } + if (my $field=$record->field($auth_type_tag)){ + $field->update($auth_type_subfield=>$authtypecode); + } + else { + $record->add_fields($auth_type_tag,'','', $auth_type_subfield=>$authtypecode); + } + + my $auth_exists=0; + my $oldRecord; if (!$authid) { my $sth=$dbh->prepare("select max(authid) from auth_header"); $sth->execute; ($authid)=$sth->fetchrow; $authid=$authid+1; ##Insert the recordID in MARC record - ##Both authid and authtypecode is expected to be in the same field. Modify if other requirements arise - $record->add_fields('001',$authid) unless $record->field('001'); - $record->add_fields('152','','','b'=>$authtypecode) unless $record->field('152'); - # $record->add_fields('100','','','b'=>$authtypecode); - warn $record->as_formatted; - $dbh->do("lock tables auth_header WRITE"); - $sth=$dbh->prepare("insert into auth_header (authid,datecreated,authtypecode,marc) values (?,now(),?,?)"); - $sth->execute($authid,$authtypecode,$record->as_usmarc); - $sth->finish; - - }else{ - ##Modified record reinsertid -# my $idfield=$record->field('001'); -# $record->delete_field($idfield); + unless ($record->field('001') && $record->field('001')->data() eq $authid){ + $record->delete_field($record->field('001')); + $record->insert_fields_ordered(MARC::Field->new('001',$authid)); + } + } else { + $auth_exists=$dbh->do(qq(select authid from auth_header where authid=?),undef,$authid); +# warn "auth_exists = $auth_exists"; + } + if ($auth_exists>0){ + $oldRecord=GetAuthority($authid); $record->add_fields('001',$authid) unless ($record->field('001')); - $record->add_fields('152','','','b'=>$authtypecode) unless ($record->field('152')); -# $record->add_fields($authfield,$authid); -# $record->add_fields($authfield2,'','',$authtypesubfield=>$authtypecode); - warn $record->as_formatted; - $dbh->do("lock tables auth_header WRITE"); - my $sth=$dbh->prepare("update auth_header set marc=? where authid=?"); - $sth->execute($record->as_usmarc,$authid); +# warn "\n\n\n enregistrement".$record->as_formatted; + my $sth=$dbh->prepare("update auth_header set authtypecode=?,marc=?,marcxml=? where authid=?"); + $sth->execute($authtypecode,$record->as_usmarc,$record->as_xml_record($format),$authid) or die $sth->errstr; $sth->finish; - } - $dbh->do("unlock tables"); - ModZebra($authid,'specialUpdate',"authorityserver"); - -# if ($record->field($linkidfield)){ -# my @fields=$record->field($linkidfield); -# -# foreach my $field (@fields){ -# my $linkid=$field->subfield($linkidsubfield) ; -# if ($linkid){ -# ##Modify the record of linked -# AUTHaddlink($dbh,$linkid,$authid); -# } -# } -# } - return ($authid); + } + else { + my $sth=$dbh->prepare("insert into auth_header (authid,datecreated,authtypecode,marc,marcxml) values (?,now(),?,?,?)"); + $sth->execute($authid,$authtypecode,$record->as_usmarc,$record->as_xml_record($format)); + $sth->finish; + } + ModZebra($authid,'specialUpdate',"authorityserver",$oldRecord,$record); + return ($authid); } -sub AUTHaddlink{ - my ($linkid,$authid)=@_; - my $dbh=C4::Context->dbh; - my $record=AUTHgetauthority($linkid); - my $authtypecode=AUTHfind_authtypecode($linkid); -#warn "adding l:$linkid,a:$authid,auth:$authtypecode"; - $record=AUTH2marcOnefieldlink($record,"auth_header.linkid",$authid,$authtypecode); - $dbh->do("lock tables auth_header WRITE"); - my $sth=$dbh->prepare("update auth_header set marc=? where authid=?"); - $sth->execute($record->as_usmarc,$linkid); - $sth->finish; - $dbh->do("unlock tables"); - ModZebra($linkid,'specialUpdate',"authorityserver"); -} -sub AUTH2marcOnefieldlink { - my ( $record, $kohafieldname, $newvalue,$authtypecode ) = @_; - my $dbh=C4::Context->dbh; - my $sth = $dbh->prepare( -"select tagfield,tagsubfield from auth_subfield_structure where authtypecode=? and kohafield=?" - ); - $sth->execute($authtypecode,$kohafieldname); - my ($tagfield,$tagsubfield)=$sth->fetchrow; - $record->add_fields( $tagfield, " ", " ", $tagsubfield => $newvalue ); - return $record; -} +=head2 DelAuthority -sub XMLgetauthority { +=over 4 - # Returns MARC::XML of the authority passed in parameter. - my ( $authid ) = @_; - my $dbh=C4::Context->dbh; - my $sth = - $dbh->prepare("select marc from auth_header where authid=? " ); - $sth->execute($authid); - my ($marc)=$sth->fetchrow; - $marc=MARC::File::USMARC::decode($marc); - my $marcxml=$marc->as_xml_record(); - return $marcxml; +$authid= &DelAuthority($authid) +Deletes $authid -} +=back +=cut -sub AUTHfind_leader{ -##Hard coded for NEU auth types -my($authtypecode)=@_; -my $leadercode; -if ($authtypecode eq "AUTH"){ -$leadercode="a"; -}elsif ($authtypecode eq "ESUB"){ -$leadercode="b"; -}elsif ($authtypecode eq "TSUB"){ -$leadercode="c"; -}else{ -$leadercode=" "; -} -return $leadercode; +sub DelAuthority { + my ($authid) = @_; + my $dbh=C4::Context->dbh; + + ModZebra($authid,"recordDelete","authorityserver",GetAuthority($authid),undef); + $dbh->do("delete from auth_header where authid=$authid") ; + } -sub AUTHgetauthority { -# Returns MARC::Record of the biblio passed in parameter. - my ($authid)=@_; +sub ModAuthority { + my ($authid,$record,$authtypecode,$merge)=@_; my $dbh=C4::Context->dbh; - my $sth=$dbh->prepare("select marc from auth_header where authid=?"); - $sth->execute($authid); - my ($marc) = $sth->fetchrow; - my $record=MARC::File::USMARC::decode($marc); + #Now rewrite the $record to table with an add + my $oldrecord=GetAuthority($authid); + $authid=AddAuthority($record,$authid,$authtypecode); - return ($record); +### If a library thinks that updating all biblios is a long process and wishes to leave that to a cron job to use merge_authotities.p +### they should have a system preference "dontmerge=1" otherwise by default biblios will be updated +### the $merge flag is now depreceated and will be removed at code cleaning + if (C4::Context->preference('MergeAuthoritiesOnUpdate') ){ + &merge($authid,$oldrecord,$authid,$record); + } else { + # save the file in tmp/modified_authorities + my $cgidir = C4::Context->intranetdir ."/cgi-bin"; + unless (opendir(DIR,"$cgidir")) { + $cgidir = C4::Context->intranetdir."/"; + closedir(DIR); + } + + my $filename = $cgidir."/tmp/modified_authorities/$authid.authid"; + open AUTH, "> $filename"; + print AUTH $authid; + close AUTH; + } + return $authid; } -sub AUTHgetauth_type { - my ($authtypecode) = @_; - my $dbh=C4::Context->dbh; - my $sth=$dbh->prepare("select * from auth_types where authtypecode=?"); - $sth->execute($authtypecode); - return $sth->fetchrow_hashref; +=head2 GetAuthorityXML + +=over 4 + +$marcxml= &GetAuthorityXML( $authid) +returns xml form of record $authid + +=back + +=cut + +sub GetAuthorityXML { + # Returns MARC::XML of the authority passed in parameter. + my ( $authid ) = @_; + if (uc(C4::Context->preference('marcflavour')) eq 'UNIMARC') { + my $dbh=C4::Context->dbh; + my $sth = $dbh->prepare("select marcxml from auth_header where authid=? " ); + $sth->execute($authid); + my ($marcxml)=$sth->fetchrow; + return $marcxml; + } + else { + # for MARC21, call GetAuthority instead of + # getting the XML directly since we may + # need to fix up the location of the authority + # code -- note that this is reasonably safe + # because GetAuthorityXML is used only by the + # indexing processes like zebraqueue_start.pl + my $record = GetAuthority($authid); + return $record->as_xml_record('MARC21'); + } } -sub AUTHmodauthority { - my ($authid,$record,$authtypecode,$merge)=@_; +=head2 GetAuthority + +=over 4 + +$record= &GetAuthority( $authid) +Returns MARC::Record of the authority passed in parameter. + +=back + +=cut + +sub GetAuthority { + my ($authid)=@_; my $dbh=C4::Context->dbh; - my ($oldrecord)=&AUTHgetauthority($authid); - if ($oldrecord eq $record) { - return; + 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); } -my $sth=$dbh->prepare("update auth_header set marc=? where authid=?"); -#warn find if linked records exist and delete them -my($linkidfield,$linkidsubfield)=AUTHfind_marc_from_kohafield("auth_header.linkid",$authtypecode); - -if ($oldrecord->field($linkidfield)){ -my @fields=$oldrecord->field($linkidfield); - foreach my $field (@fields){ -my $linkid=$field->subfield($linkidsubfield) ; - if ($linkid){ - ##Modify the record of linked - my $linkrecord=AUTHgetauthority($linkid); - my $linktypecode=AUTHfind_authtypecode($linkid); - my ( $linkidfield2,$linkidsubfield2)=AUTHfind_marc_from_kohafield("auth_header.linkid",$linktypecode); - my @linkfields=$linkrecord->field($linkidfield2); - foreach my $linkfield (@linkfields){ - if ($linkfield->subfield($linkidsubfield2) eq $authid){ - $linkrecord->delete_field($linkfield); - $sth->execute($linkrecord->as_usmarc,$linkid); - ModZebra($linkid,'specialUpdate',"authorityserver"); - } - }#foreach linkfield - } - }#foreach linkid + return ($record); } -#Now rewrite the $record to table with an add -$authid=AUTHaddauthority($record,$authid,$authtypecode); +=head2 GetAuthType -### If a library thinks that updating all biblios is a long process and wishes to leave that to a cron job to use merge_authotities.p -### they should have a system preference "dontmerge=1" otherwise by default biblios will be updated -### the $merge flag is now depreceated and will be removed at code cleaning +=over 4 -if (C4::Context->preference('dontmerge') ){ -# save the file in localfile/modified_authorities - my $cgidir = C4::Context->intranetdir ."/cgi-bin"; - unless (opendir(DIR,"$cgidir")) { - $cgidir = C4::Context->intranetdir."/"; - } +$result = &GetAuthType($authtypecode) - my $filename = $cgidir."/localfile/modified_authorities/$authid.authid"; - open AUTH, "> $filename"; - print AUTH $authid; - close AUTH; -} else { - &merge($authid,$record,$authid,$record); -} -return $authid; -} +=back -sub AUTHdelauthority { - my ($authid,$keep_biblio) = @_; - my $dbh=C4::Context->dbh; -# if the keep_biblio is set to 1, then authority entries in biblio are preserved. +If the authority type specified by C<$authtypecode> exists, +returns a hashref of the type's fields. If the type +does not exist, returns undef. -ModZebra($authid,"recordDelete","authorityserver"); - $dbh->do("delete from auth_header where authid=$authid") ; +=cut -# FIXME : delete or not in biblio tables (depending on $keep_biblio flag) +sub GetAuthType { + my ($authtypecode) = @_; + my $dbh=C4::Context->dbh; + my $sth; + if (defined $authtypecode){ # NOTE - in MARC21 framework, '' is a valid authority + # type (FIXME but why?) + $sth=$dbh->prepare("select * from auth_types where authtypecode=?"); + $sth->execute($authtypecode); + if (my $res = $sth->fetchrow_hashref) { + return $res; + } + } + return; } + sub AUTHhtml2marc { my ($rtags,$rsubfields,$rvalues,%indicators) = @_; my $dbh=C4::Context->dbh; @@ -624,9 +805,20 @@ sub AUTHhtml2marc { return $record; } +=head2 FindDuplicateAuthority + +=over 4 + +$record= &FindDuplicateAuthority( $record, $authtypecode) +return $authid,Summary if duplicate is found. + +Comments : an improvement would be to return All the records that match. + +=back +=cut -sub FindDuplicate { +sub FindDuplicateAuthority { my ($record,$authtypecode)=@_; # warn "IN for ".$record->as_formatted; @@ -636,138 +828,218 @@ sub FindDuplicate { $sth->execute($authtypecode); my ($auth_tag_to_report) = $sth->fetchrow; $sth->finish; -# warn "record :".$record->as_formatted." authtattoreport :$auth_tag_to_report"; - # build a request for authoritysearch +# warn "record :".$record->as_formatted." auth_tag_to_report :$auth_tag_to_report"; + # build a request for SearchAuthorities my $query='at='.$authtypecode.' '; - map {$query.= " and he=\"".$_->[1]."\"" if ($_->[0]=~/[A-z]/)} $record->field($auth_tag_to_report)->subfields() if $record->field($auth_tag_to_report); - my ($error,$results)=SimpleSearch($query,"authorityserver"); + 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]/); + } + } + my ($error, $results, $total_hits)=SimpleSearch( $query, 0, 1, [ "authorityserver" ] ); # there is at least 1 result => return the 1st one if (@$results>0) { my $marcrecord = MARC::File::USMARC::decode($results->[0]); - return $marcrecord->field('001')->data,getsummary($marcrecord,$marcrecord->field('001')->data,$authtypecode); + return $marcrecord->field('001')->data,BuildSummary($marcrecord,$marcrecord->field('001')->data,$authtypecode); } # no result, returns nothing return; } -sub getsummary{ -## give this a Marc record to return summary -my ($record,$authid,$authtypecode)=@_; - -my $dbh=C4::Context->dbh; -# my $authtypecode = AUTHfind_authtypecode($dbh,$authid); - my $authref = getauthtype($authtypecode); - my $summary = $authref->{summary}; - my @fields = $record->fields(); -# chop $tags_using_authtype; # FIXME: why commented out? - my $reported_tag; - - # if the library has a summary defined, use it. Otherwise, build a standard one - if ($summary) { - my @fields = $record->fields(); -# $reported_tag = '$9'.$result[$counter]; - foreach my $field (@fields) { - my $tag = $field->tag(); - my $tagvalue = $field->as_string(); - $summary =~ s/\[(.?.?.?.?)$tag\*(.*?)]/$1$tagvalue$2\[$1$tag$2]/g; - if ($tag<10) { - if ($tag eq '001') { - $reported_tag.='$3'.$field->data(); - } +=head2 BuildSummary - } else { - my @subf = $field->subfields; - for my $i (0..$#subf) { - my $subfieldcode = $subf[$i][0]; - my $subfieldvalue = $subf[$i][1]; - my $tagsubf = $tag.$subfieldcode; - $summary =~ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g; -# if ($tag eq $auth_tag_to_report) { -# $reported_tag.='$'.$subfieldcode.$subfieldvalue; -# } - } - } - } - $summary =~ s/\[(.*?)]//g; - $summary =~ s/\n/
/g; - } else { - my $heading; # = $authref->{summary}; - my $altheading; - my $seeheading; - my $see; - my @fields = $record->fields(); - 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..')) { - $heading.= $field->as_string(); - } - # rejected form(s) - foreach my $field ($record->field('4..')) { - $summary.= "   ".$field->as_string()."
"; - $summary.= "      see: ".$heading."
"; - } - # see : - foreach my $field ($record->field('5..')) { - $summary.= "   ".$field->as_string()."
"; - $summary.= "      see: ".$heading."
"; - } - # // form - foreach my $field ($record->field('7..')) { - $seeheading.= "      see also: ".$field->as_string()."
"; - $altheading.= "   ".$field->as_string()."
"; - $altheading.= "      see also: ".$heading."
"; - } - $summary = "".$heading."
".$seeheading.$altheading.$summary; - } else { - # construct MARC21 summary - foreach my $field ($record->field('1..')) { - if ($record->field('100')) { - $heading.= $field->as_string('abcdefghjklmnopqrstvxyz68'); - } elsif ($record->field('110')) { - $heading.= $field->as_string('abcdefghklmnoprstvxyz68'); - } elsif ($record->field('111')) { - $heading.= $field->as_string('acdefghklnpqstvxyz68'); - } elsif ($record->field('130')) { - $heading.= $field->as_string('adfghklmnoprstvxyz68'); - } elsif ($record->field('148')) { - $heading.= $field->as_string('abvxyz68'); - } elsif ($record->field('150')) { - # $heading.= $field->as_string('abvxyz68'); - $heading.= $field->as_formatted(); - my $tag=$field->tag(); - $heading=~s /^$tag//g; - $heading =~s /\_/\$/g; - } elsif ($record->field('151')) { - $heading.= $field->as_string('avxyz68'); - } elsif ($record->field('155')) { - $heading.= $field->as_string('abvxyz68'); - } elsif ($record->field('180')) { - $heading.= $field->as_string('vxyz68'); - } elsif ($record->field('181')) { - $heading.= $field->as_string('vxyz68'); - } elsif ($record->field('182')) { - $heading.= $field->as_string('vxyz68'); - } elsif ($record->field('185')) { - $heading.= $field->as_string('vxyz68'); - } else { - $heading.= $field->as_string(); - } - } #See From - foreach my $field ($record->field('4..')) { - $seeheading.= "   ".$field->as_string()."
"; - $seeheading.= "      see: ".$seeheading."
"; - } #See Also - foreach my $field ($record->field('5..')) { - $altheading.= "      see also: ".$field->as_string()."
"; - $altheading.= "   ".$field->as_string()."
"; - $altheading.= "      see also: ".$altheading."
"; - } - $summary.=$heading.$seeheading.$altheading; - } +=over 4 + +$text= &BuildSummary( $record, $authid, $authtypecode) +return HTML encoded Summary + +Comment : authtypecode can be infered from both record and authid. +Moreover, authid can also be inferred from $record. +Would it be interesting to delete those things. + +=back + +=cut + +sub BuildSummary{ +## give this a Marc record to return summary + my ($record,$authid,$authtypecode)=@_; + my $dbh=C4::Context->dbh; + my $summary; + # handle $authtypecode is NULL or eq "" + if ($authtypecode) { + my $authref = GetAuthType($authtypecode); + $summary = $authref->{summary}; + } + # FIXME: should use I18N.pm + my %language; + $language{'fre'}="Français"; + $language{'eng'}="Anglais"; + $language{'ger'}="Allemand"; + $language{'ita'}="Italien"; + $language{'spa'}="Espagnol"; + my %thesaurus; + $thesaurus{'1'}="Peuples"; + $thesaurus{'2'}="Anthroponymes"; + $thesaurus{'3'}="Oeuvres"; + $thesaurus{'4'}="Chronologie"; + $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 + # can work as a display template. However, this doesn't + # suit the MARC21 version, so for now the "templating" + # feature will be enabled only for UNIMARC for backwards + # compatibility. + if ($summary and C4::Context->preference('marcflavour') eq 'UNIMARC') { + my @fields = $record->fields(); + # $reported_tag = '$9'.$result[$counter]; + foreach my $field (@fields) { + my $tag = $field->tag(); + my $tagvalue = $field->as_string(); + $summary =~ s/\[(.?.?.?.?)$tag\*(.*?)]/$1$tagvalue$2\[$1$tag$2]/g; + if ($tag<10) { + if ($tag eq '001') { + $reported_tag.='$3'.$field->data(); + } + } else { + my @subf = $field->subfields; + for my $i (0..$#subf) { + my $subfieldcode = $subf[$i][0]; + my $subfieldvalue = $subf[$i][1]; + my $tagsubf = $tag.$subfieldcode; + $summary =~ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g; } -return $summary; + } + } + $summary =~ s/\[(.*?)]//g; + $summary =~ s/\n/
/g; + } else { + my $heading; + my $authid; + my $altheading; + my $seealso; + my $broaderterms; + my $narrowerterms; + my $see; + my $seeheading; + my $notes; + my @fields = $record->fields(); + 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..')) { + $heading.= $field->subfield('a'); + $authid=$field->subfield('3'); + } + # rejected form(s) + foreach my $field ($record->field('3..')) { + $notes.= ''.$field->subfield('a')."\n"; + } + foreach my $field ($record->field('4..')) { + if ($field->subfield('2')) { + my $thesaurus = "thes. : ".$thesaurus{"$field->subfield('2')"}." : "; + $see.= ''.$thesaurus.$field->subfield('a')." -- \n"; + } + } + # see : + foreach my $field ($record->field('5..')) { + + if (($field->subfield('5')) && ($field->subfield('a')) && ($field->subfield('5') eq 'g')) { + $broaderterms.= ' '.$field->subfield('a')." -- \n"; + } elsif (($field->subfield('5')) && ($field->subfield('a')) && ($field->subfield('5') eq 'h')){ + $narrowerterms.= ''.$field->subfield('a')." -- \n"; + } elsif ($field->subfield('a')) { + $seealso.= ''.$field->subfield('a')." -- \n"; + } + } + # // form + foreach my $field ($record->field('7..')) { + my $lang = substr($field->subfield('8'),3,3); + $seeheading.= ' En '.$language{$lang}.' : '.$field->subfield('a')."
\n"; + } + $broaderterms =~s/-- \n$//; + $narrowerterms =~s/-- \n$//; + $seealso =~s/-- \n$//; + $see =~s/-- \n$//; + $summary = "".$heading."
".($notes?"$notes
":""); + $summary.= '

TG : '.$broaderterms.'

' if ($broaderterms); + $summary.= '

TS : '.$narrowerterms.'

' if ($narrowerterms); + $summary.= '

TA : '.$seealso.'

' if ($seealso); + $summary.= '

EP : '.$see.'

' if ($see); + $summary.= '

'.$seeheading.'

' if ($seeheading); + } else { + # construct MARC21 summary + # FIXME - looping over 1XX is questionable + # since MARC21 authority should have only one 1XX + foreach my $field ($record->field('1..')) { + next if "152" eq $field->tag(); # FIXME - 152 is not a good tag to use + # in MARC21 -- purely local tags really ought to be + # 9XX + if ($record->field('100')) { + $heading.= $field->as_string('abcdefghjklmnopqrstvxyz68'); + } elsif ($record->field('110')) { + $heading.= $field->as_string('abcdefghklmnoprstvxyz68'); + } elsif ($record->field('111')) { + $heading.= $field->as_string('acdefghklnpqstvxyz68'); + } elsif ($record->field('130')) { + $heading.= $field->as_string('adfghklmnoprstvxyz68'); + } elsif ($record->field('148')) { + $heading.= $field->as_string('abvxyz68'); + } elsif ($record->field('150')) { + # $heading.= $field->as_string('abvxyz68'); + $heading.= $field->as_formatted(); + my $tag=$field->tag(); + $heading=~s /^$tag//g; + $heading =~s /\_/\$/g; + } elsif ($record->field('151')) { + $heading.= $field->as_string('avxyz68'); + } elsif ($record->field('155')) { + $heading.= $field->as_string('abvxyz68'); + } elsif ($record->field('180')) { + $heading.= $field->as_string('vxyz68'); + } elsif ($record->field('181')) { + $heading.= $field->as_string('vxyz68'); + } elsif ($record->field('182')) { + $heading.= $field->as_string('vxyz68'); + } elsif ($record->field('185')) { + $heading.= $field->as_string('vxyz68'); + } else { + $heading.= $field->as_string(); + } + } #See From + foreach my $field ($record->field('4..')) { + $seeheading.= "
      used for/see from: ".$field->as_string(); + } #See Also + foreach my $field ($record->field('5..')) { + $altheading.= "
      see also: ".$field->as_string(); + } + $summary .= ": " if $summary; + $summary.=$heading.$seeheading.$altheading; + } + } + return $summary; } + +=head2 BuildUnimarcHierarchies + +=over 4 + +$text= &BuildUnimarcHierarchies( $authid, $force) +return text containing trees for hierarchies +for them to be stored in auth_header + +Example of text: +122,1314,2452;1324,2342,3,2452 + +=back + +=cut + sub BuildUnimarcHierarchies{ my $authid = shift @_; # warn "authid : $authid"; @@ -775,18 +1047,17 @@ sub BuildUnimarcHierarchies{ my @globalresult; my $dbh=C4::Context->dbh; my $hierarchies; - my $data = AUTHgetheader($authid); - + my $data = GetHeaderAuthority($authid); if ($data->{'authtrees'} and not $force){ return $data->{'authtrees'}; } elsif ($data->{'authtrees'}){ $hierarchies=$data->{'authtrees'}; } else { - my $record = AUTHgetauthority($authid); + my $record = GetAuthority($authid); my $found; foreach my $field ($record->field('550')){ if ($field->subfield('5') && $field->subfield('5') eq 'g'){ - my $parentrecord = AUTHgetauthority($field->subfield('3')); + my $parentrecord = GetAuthority($field->subfield('3')); my $localresult=$hierarchies; my $trees; $trees = BuildUnimarcHierarchies($field->subfield('3')); @@ -807,142 +1078,322 @@ sub BuildUnimarcHierarchies{ #Unless there is no ancestor, I am alone. $hierarchies="$authid" unless ($hierarchies); } - AUTHsavetrees($authid,$hierarchies); + AddAuthorityTrees($authid,$hierarchies); return $hierarchies; } +=head2 BuildUnimarcHierarchy + +=over 4 + +$ref= &BuildUnimarcHierarchy( $record, $class,$authid) +return a hashref in order to display hierarchy for record and final Authid $authid + +"loopparents" +"loopchildren" +"class" +"loopauthid" +"current_value" +"value" + +"ifparents" +"ifchildren" +Those two latest ones should disappear soon. + +=back + +=cut + sub BuildUnimarcHierarchy{ - my $record = shift @_; - my $class = shift @_; - my $authid_constructed = shift @_; - my $authid=$record->subfield('250','3'); - my %cell; - my $parents=""; my $children=""; - my (@loopparents,@loopchildren); - foreach my $field ($record->field('550')){ - if ($field->subfield('5') && $field->subfield('a')){ - if ($field->subfield('5') eq 'h'){ - push @loopchildren, { "childauthid"=>$field->subfield('3'),"childvalue"=>$field->subfield('a')}; - }elsif ($field->subfield('5') eq 'g'){ - push @loopparents, { "parentauthid"=>$field->subfield('3'),"parentvalue"=>$field->subfield('a')}; - } - # brothers could get in there with an else - } - } - $cell{"ifparents"}=1 if (scalar(@loopparents)>0); - $cell{"ifchildren"}=1 if (scalar(@loopchildren)>0); - $cell{"loopparents"}=\@loopparents if (scalar(@loopparents)>0); - $cell{"loopchildren"}=\@loopchildren if (scalar(@loopchildren)>0); - $cell{"class"}=$class; - $cell{"loopauthid"}=$authid; - $cell{"current_value"} =1 if $authid eq $authid_constructed; - $cell{"value"}=$record->subfield('250',"a"); - return \%cell; + my $record = shift @_; + my $class = shift @_; + my $authid_constructed = shift @_; + my $authid=$record->field('001')->data(); + my %cell; + my $parents=""; my $children=""; + my (@loopparents,@loopchildren); + foreach my $field ($record->field('550')){ + if ($field->subfield('5') && $field->subfield('a')){ + if ($field->subfield('5') eq 'h'){ + push @loopchildren, { "childauthid"=>$field->subfield('3'),"childvalue"=>$field->subfield('a')}; + }elsif ($field->subfield('5') eq 'g'){ + push @loopparents, { "parentauthid"=>$field->subfield('3'),"parentvalue"=>$field->subfield('a')}; + } + # brothers could get in there with an else + } + } + $cell{"ifparents"}=1 if (scalar(@loopparents)>0); + $cell{"ifchildren"}=1 if (scalar(@loopchildren)>0); + $cell{"loopparents"}=\@loopparents if (scalar(@loopparents)>0); + $cell{"loopchildren"}=\@loopchildren if (scalar(@loopchildren)>0); + $cell{"class"}=$class; + $cell{"loopauthid"}=$authid; + $cell{"current_value"} =1 if $authid eq $authid_constructed; + $cell{"value"}=$record->subfield('2..',"a"); + return \%cell; } -sub AUTHgetheader{ - my $authid = shift @_; - my $sql= "SELECT * from auth_header WHERE authid = ?"; - my $dbh=C4::Context->dbh; - my $rq= $dbh->prepare($sql); - $rq->execute($authid); - my $data= $rq->fetchrow_hashref; - return $data; +=head2 GetHeaderAuthority + +=over 4 + +$ref= &GetHeaderAuthority( $authid) +return a hashref in order auth_header table data + +=back + +=cut + +sub GetHeaderAuthority{ + my $authid = shift @_; + my $sql= "SELECT * from auth_header WHERE authid = ?"; + my $dbh=C4::Context->dbh; + my $rq= $dbh->prepare($sql); + $rq->execute($authid); + my $data= $rq->fetchrow_hashref; + return $data; } -sub AUTHsavetrees{ - my $authid = shift @_; - my $trees = shift @_; - my $sql= "UPDATE IGNORE auth_header set authtrees=? WHERE authid = ?"; - my $dbh=C4::Context->dbh; - my $rq= $dbh->prepare($sql); - $rq->execute($trees,$authid); +=head2 AddAuthorityTrees + +=over 4 + +$ref= &AddAuthorityTrees( $authid, $trees) +return success or failure + +=back + +=cut + +sub AddAuthorityTrees{ + my $authid = shift @_; + my $trees = shift @_; + my $sql= "UPDATE IGNORE auth_header set authtrees=? WHERE authid = ?"; + my $dbh=C4::Context->dbh; + my $rq= $dbh->prepare($sql); + return $rq->execute($trees,$authid); } +=head2 merge + +=over 4 + +$ref= &merge(mergefrom,$MARCfrom,$mergeto,$MARCto) + + +Could add some feature : Migrating from a typecode to an other for instance. +Then we should add some new parameter : bibliotargettag, authtargettag + +=back + +=cut sub merge { my ($mergefrom,$MARCfrom,$mergeto,$MARCto) = @_; + my ($counteditedbiblio,$countunmodifiedbiblio,$counterrors)=(0,0,0); my $dbh=C4::Context->dbh; - my $authtypecodefrom = AUTHfind_authtypecode($mergefrom); - my $authtypecodeto = AUTHfind_authtypecode($mergeto); + my $authtypecodefrom = GetAuthTypeCode($mergefrom); + my $authtypecodeto = GetAuthTypeCode($mergeto); +# warn "mergefrom : $authtypecodefrom $mergefrom mergeto : $authtypecodeto $mergeto "; # return if authority does not exist - my @X = $MARCfrom->fields(); - return if $#X == -1; - @X = $MARCto->fields(); - return if $#X == -1; - - + return "error MARCFROM not a marcrecord ".Data::Dumper::Dumper($MARCfrom) if scalar($MARCfrom->fields()) == 0; + return "error MARCTO not a marcrecord".Data::Dumper::Dumper($MARCto) if scalar($MARCto->fields()) == 0; # search the tag to report my $sth = $dbh->prepare("select auth_tag_to_report from auth_types where authtypecode=?"); $sth->execute($authtypecodefrom); - my ($auth_tag_to_report) = $sth->fetchrow; - + my ($auth_tag_to_report_from) = $sth->fetchrow; + $sth->execute($authtypecodeto); + my ($auth_tag_to_report_to) = $sth->fetchrow; + my @record_to; - @record_to = $MARCto->field($auth_tag_to_report)->subfields() if $MARCto->field($auth_tag_to_report); + @record_to = $MARCto->field($auth_tag_to_report_to)->subfields() if $MARCto->field($auth_tag_to_report_to); my @record_from; - @record_from = $MARCfrom->field($auth_tag_to_report)->subfields() if $MARCfrom->field($auth_tag_to_report); + @record_from = $MARCfrom->field($auth_tag_to_report_from)->subfields() if $MARCfrom->field($auth_tag_to_report_from); + 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); + $oConnection->option("preferredRecordSyntax"=>"XML"); + 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(); + push @reccache, $marcdata; + $z++; + } + $oConnection->destroy(); + } + #warn scalar(@reccache)." biblios to update"; + # Get All candidate Tags for the change + # (This will reduce the search scope in marc records). $sth = $dbh->prepare("select distinct tagfield from marc_subfield_structure where authtypecode=?"); $sth->execute($authtypecodefrom); -my @tags_using_authtype; + my @tags_using_authtype; while (my ($tagfield) = $sth->fetchrow) { - push @tags_using_authtype,$tagfield."9" ; + push @tags_using_authtype,$tagfield ; } - - # now, find every biblio using this authority -### try ZOOM search here -my $oConnection=C4::Context->Zconn("biblioserver"); -my $query; -$query= "an= ".$mergefrom; -my $oResult = $oConnection->search(new ZOOM::Query::CCL2RPN( $query, $oConnection )); -my $count=$oResult->size() if ($oResult); -my @reccache; -my $z=0; -while ( $z<$count ) { -my $rec; - $rec=$oResult->record($z); - my $marcdata = $rec->raw(); -push @reccache, $marcdata; -$z++; -} -$oResult->destroy(); -foreach my $marc(@reccache){ - -my $update; - my $marcrecord; - $marcrecord = MARC::File::USMARC::decode($marc); - foreach my $tagfield (@tags_using_authtype){ - $tagfield=substr($tagfield,0,3); - my @tags = $marcrecord->field($tagfield); - foreach my $tag (@tags){ - my $tagsubs=$tag->subfield("9"); -#warn "$tagfield:$tagsubs:$mergefrom"; - if ($tagsubs== $mergefrom) { - - $tag->update("9" =>$mergeto); - foreach my $subfield (@record_to) { -# warn "$subfield,$subfield->[0],$subfield->[1]"; - $tag->update($subfield->[0] =>$subfield->[1]); - }#for $subfield + my $tag_to=0; + if ($authtypecodeto ne $authtypecodefrom){ + # If many tags, take the first + $sth->execute($authtypecodeto); + $tag_to=$sth->fetchrow; + #warn $tag_to; + } + # BulkEdit marc records + # May be used as a template for a bulkedit field + foreach my $marcrecord(@reccache){ + my $update; + $marcrecord= MARC::Record->new_from_xml($marcrecord,"utf8",C4::Context->preference("marcflavour")) unless(C4::Context->preference('NoZebra')); + foreach my $tagfield (@tags_using_authtype){ +# warn "tagfield : $tagfield "; + foreach my $field ($marcrecord->field($tagfield)){ + 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); + foreach my $subfield (@record_to) { + $field_to->add_subfields($subfield->[0] =>$subfield->[1]); + } + $marcrecord->delete_field($field); + $marcrecord->insert_grouped_field($field_to); + $update=1; + } + }#for each tag + }#foreach tagfield + my ($bibliotag,$bibliosubf) = GetMarcFromKohaField("biblio.biblionumber","") ; + my $biblionumber; + if ($bibliotag<10){ + $biblionumber=$marcrecord->field($bibliotag)->data; } - $marcrecord->delete_field($tag); - $marcrecord->add_fields($tag); - $update=1; - }#for each tag - }#foreach tagfield - my $oldbiblio = TransformMarcToKoha($dbh,$marcrecord,"") ; - if ($update==1){ - # FIXME : this NEWmodbiblio does not exist anymore... - &ModBiblio($marcrecord,$oldbiblio->{'biblionumber'},GetFrameworkCode($oldbiblio->{'biblionumber'})) ; + else { + $biblionumber=$marcrecord->subfield($bibliotag,$bibliosubf); } - -}#foreach $marc + unless ($biblionumber){ + warn "pas de numéro de notice bibliographique dans : ".$marcrecord->as_formatted; + next; + } + if ($update==1){ + &ModBiblio($marcrecord,$biblionumber,GetFrameworkCode($biblionumber)) ; + $counteditedbiblio++; + warn $counteditedbiblio if (($counteditedbiblio % 10) and $ENV{DEBUG}); + } + }#foreach $marc + return $counteditedbiblio; + # now, find every other authority linked with this authority + # now, find every other authority linked with this authority +# my $oConnection=C4::Context->Zconn("authorityserver"); +# my $query; +# # att 9210 Auth-Internal-authtype +# # att 9220 Auth-Internal-LN +# # ccl.properties to add for authorities +# $query= "= ".$mergefrom; +# my $oResult = $oConnection->search(new ZOOM::Query::CCL2RPN( $query, $oConnection )); +# my $count=$oResult->size() if ($oResult); +# my @reccache; +# my $z=0; +# while ( $z<$count ) { +# my $rec; +# $rec=$oResult->record($z); +# my $marcdata = $rec->raw(); +# push @reccache, $marcdata; +# $z++; +# } +# $oResult->destroy(); +# foreach my $marc(@reccache){ +# my $update; +# my $marcrecord; +# $marcrecord = MARC::File::USMARC::decode($marc); +# foreach my $tagfield (@tags_using_authtype){ +# $tagfield=substr($tagfield,0,3); +# my @tags = $marcrecord->field($tagfield); +# foreach my $tag (@tags){ +# my $tagsubs=$tag->subfield("9"); +# #warn "$tagfield:$tagsubs:$mergefrom"; +# if ($tagsubs== $mergefrom) { +# $tag->update("9" =>$mergeto); +# foreach my $subfield (@record_to) { +# # warn "$subfield,$subfield->[0],$subfield->[1]"; +# $tag->update($subfield->[0] =>$subfield->[1]); +# }#for $subfield +# } +# $marcrecord->delete_field($tag); +# $marcrecord->add_fields($tag); +# $update=1; +# }#for each tag +# }#foreach tagfield +# my $authoritynumber = TransformMarcToKoha($dbh,$marcrecord,"") ; +# if ($update==1){ +# &ModAuthority($marcrecord,$authoritynumber,GetAuthTypeCode($authoritynumber)) ; +# } +# +# }#foreach $marc }#sub -END { } # module clean-up code here (global destructor) + +=head2 get_auth_type_location + +=over 4 + +my ($tag, $subfield) = get_auth_type_location($auth_type_code); =back +Get the tag and subfield used to store the heading type +for indexing purposes. The C<$auth_type> parameter is +optional; if it is not supplied, assume ''. + +This routine searches the MARC authority framework +for the tag and subfield whose kohafield is +C; if no such field is +defined in the framework, default to the hardcoded value +specific to the MARC format. + +=cut + +sub get_auth_type_location { + my $auth_type_code = @_ ? shift : ''; + + my ($tag, $subfield) = GetAuthMARCFromKohaField('auth_header.authtypecode', $auth_type_code); + if (defined $tag and defined $subfield and $tag != 0 and $subfield != 0) { + return ($tag, $subfield); + } else { + if (C4::Context->preference('marcflavour') eq "MARC21") { + return C4::AuthoritiesMarc::MARC21::default_auth_type_location(); + } else { + return C4::AuthoritiesMarc::UNIMARC::default_auth_type_location(); + } + } +} + +END { } # module clean-up code here (global destructor) + +1; +__END__ + =head1 AUTHOR Koha Developement team @@ -951,171 +1402,3 @@ Paul POULAIN paul.poulain@free.fr =cut -# $Id$ -# $Log$ -# Revision 1.41 2007/03/29 13:30:31 tipaul -# Code cleaning : -# == Biblio.pm cleaning (useless) == -# * some sub declaration dropped -# * removed modbiblio sub -# * removed moditem sub -# * removed newitems. It was used only in finishrecieve. Replaced by a Koha2Marc+AddItem, that is better. -# * removed MARCkoha2marcItem -# * removed MARCdelsubfield declaration -# * removed MARCkoha2marcBiblio -# -# == Biblio.pm cleaning (naming conventions) == -# * MARCgettagslib renamed to GetMarcStructure -# * MARCgetitems renamed to GetMarcItem -# * MARCfind_frameworkcode renamed to GetFrameworkCode -# * MARCmarc2koha renamed to TransformMarcToKoha -# * MARChtml2marc renamed to TransformHtmlToMarc -# * MARChtml2xml renamed to TranformeHtmlToXml -# * zebraop renamed to ModZebra -# -# == MARC=OFF == -# * removing MARC=OFF related scripts (in cataloguing directory) -# * removed checkitems (function related to MARC=off feature, that is completly broken in head. If someone want to reintroduce it, hard work coming...) -# * removed getitemsbybiblioitem (used only by MARC=OFF scripts, that is removed as well) -# -# Revision 1.40 2007/03/28 10:39:16 hdl -# removing $dbh as a parameter in AuthoritiesMarc functions -# And reporting all differences into the scripts taht relies on those functions. -# -# Revision 1.39 2007/03/16 01:25:08 kados -# Using my precrash CVS copy I did the following: -# -# cvs -z3 -d:ext:kados@cvs.savannah.nongnu.org:/sources/koha co -P koha -# find koha.precrash -type d -name "CVS" -exec rm -v {} \; -# cp -r koha.precrash/* koha/ -# cd koha/ -# cvs commit -# -# This should in theory put us right back where we were before the crash -# -# Revision 1.39 2007/03/12 22:16:31 kados -# chcking for field before calling subfields -# -# Revision 1.38 2007/03/09 14:31:47 tipaul -# rel_3_0 moved to HEAD -# -# Revision 1.28.2.17 2007/02/05 13:16:08 hdl -# Removing Link from AuthoritiesMARC summary (caused a problem owed to the API differences between opac and intranet) -# + removing $dbh in authoritysearch -# + adding links in templates on summaries to go to full view. -# (no more links in popup authorities. or should we add it ?) -# -# Revision 1.28.2.16 2007/02/02 18:07:42 hdl -# Sorting and searching for exact term now works. -# -# Revision 1.28.2.15 2007/01/24 10:17:47 hdl -# FindDuplicate Now works. -# Be AWARE that it needs a change ccl.properties. -# -# Revision 1.28.2.14 2007/01/10 14:40:11 hdl -# Adding Authorities tree. -# -# Revision 1.28.2.13 2007/01/09 15:18:09 hdl -# Adding an to ccl.properties to allow ccl search for authority-numbers. -# Fixing Some problems with the previous modification to allow pqf search to work for more than one page. -# Using search for an= for an authority-Number. -# -# Revision 1.28.2.12 2007/01/09 13:51:31 hdl -# Bug Fixing : AUTHcount_usage used *synchronous* connection where biblio used ****asynchronous**** one. -# First try to get it work. -# -# Revision 1.28.2.11 2007/01/05 14:37:26 btoumi -# bug fix : remove wrong field in sql syntaxe from auth_subfield_structure table -# -# Revision 1.28.2.10 2007/01/04 13:11:08 tipaul -# commenting 2 zconn destroy -# -# Revision 1.28.2.9 2006/12/22 15:09:53 toins -# removing C4::Database; -# -# Revision 1.28.2.8 2006/12/20 17:13:19 hdl -# modifying use of GILS into use of @attr 1=Koha-Auth-Number -# -# Revision 1.28.2.7 2006/12/18 16:45:38 tipaul -# FIXME upcased -# -# Revision 1.28.2.6 2006/12/07 16:45:43 toins -# removing warn compilation. (perl -wc) -# -# Revision 1.28.2.5 2006/12/06 14:19:59 hdl -# ABugFixing : Authority count Management. -# -# Revision 1.28.2.4 2006/11/17 13:18:58 tipaul -# code cleaning : removing use of "bib", and replacing with "biblionumber" -# -# WARNING : I tried to do carefully, but there are probably some mistakes. -# So if you encounter a problem you didn't have before, look for this change !!! -# anyway, I urge everybody to use only "biblionumber", instead of "bib", "bi", "biblio" or anything else. will be easier to maintain !!! -# -# Revision 1.28.2.3 2006/11/17 11:17:30 tipaul -# code cleaning : removing use of "bib", and replacing with "biblionumber" -# -# WARNING : I tried to do carefully, but there are probably some mistakes. -# So if you encounter a problem you didn't have before, look for this change !!! -# anyway, I urge everybody to use only "biblionumber", instead of "bib", "bi", "biblio" or anything else. will be easier to maintain !!! -# -# Revision 1.28.2.2 2006/10/12 22:04:47 hdl -# Authorities working with zebra. -# zebra Configuration files are comitted next. -# -# Revision 1.9.2.17.2.2 2006/07/27 16:34:56 kados -# syncing with rel_2_2 .. .untested. -# -# Revision 1.9.2.17.2.1 2006/05/28 18:49:12 tgarip1957 -# This is an unusual commit. The main purpose is a working model of Zebra on a modified rel2_2. -# Any questions regarding these commits should be asked to Joshua Ferraro unless you are Joshua whom I'll report to -# -# Revision 1.9.2.6 2005/06/07 10:02:00 tipaul -# porting dictionnary search from head to 2.2. there is now a ... facing titles, author & subject, to search in biblio & authorities existing values. -# -# Revision 1.9.2.5 2005/05/31 14:50:46 tipaul -# fix for authority merging. There was a bug on official installs -# -# Revision 1.9.2.4 2005/05/30 11:24:15 tipaul -# fixing a bug : when a field was repeated, the last field was also repeated. (Was due to the "empty" field in html between fields : to separate fields, in html, an empty field is automatically added. in AUTHhtml2marc, this empty field was not discarded correctly) -# -# Revision 1.9.2.3 2005/04/28 08:45:33 tipaul -# porting FindDuplicate feature for authorities from HEAD to rel_2_2, works correctly now. -# -# Revision 1.9.2.2 2005/02/28 14:03:13 tipaul -# * adding search on "main entry" (ie $a subfield) on a given authority (the "search everywhere" field is still here). -# * adding a select box to requet "contain" or "begin with" search. -# * fixing some bug in authority search (related to "main entry" search) -# -# Revision 1.9.2.1 2005/02/24 13:12:13 tipaul -# saving authority modif in a text file. This will be used soon with another script (in crontab). The script in crontab will retrieve every authorityid in the directory localfile/authorities and modify every biblio using this authority. Those modifs may be long. So they can't be done through http, because we may encounter a webserver timeout, and kill the process before end of the job. -# So, it will be done through a cron job. -# (/me agree we need some doc for command line scripts) -# -# Revision 1.9 2004/12/23 09:48:11 tipaul -# Minor changes in summary "exploding" (the 3 digits AFTER the subfield were not on the right place). -# -# Revision 1.8 2004/11/05 10:11:39 tipaul -# export auth_count_usage (bugfix) -# -# Revision 1.7 2004/09/23 16:13:00 tipaul -# Bugfix in modification -# -# Revision 1.6 2004/08/18 16:00:24 tipaul -# fixes for authorities management -# -# Revision 1.5 2004/07/05 13:37:22 doxulting -# First step for working authorities -# -# Revision 1.4 2004/06/22 11:35:37 tipaul -# removing % at the beginning of a string to avoid loooonnnngggg searchs -# -# Revision 1.3 2004/06/17 08:02:13 tipaul -# merging tag & subfield in auth_word for better perfs -# -# Revision 1.2 2004/06/10 08:29:01 tipaul -# MARC authority management (continued) -# -# Revision 1.1 2004/06/07 07:35:01 tipaul -# MARC authority management package -#