# 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 C4::AuthoritiesMarc::MARC21;
+use C4::AuthoritiesMarc::UNIMARC;
+use C4::Charset;
use vars qw($VERSION @ISA @EXPORT);
-# set the version for version checking
-$VERSION = do { my @v = '$Revision$' =~ /\d+/g; shift(@v).".".join( "_", map { sprintf "%03d", $_ } @v ); };
-
-@ISA = qw(Exporter);
-@EXPORT = qw(
- &GetTagsLabels
- &GetAuthType
- &GetAuthTypeCode
- &GetAuthMARCFromKohaField
- &AUTHhtml2marc
-
- &AddAuthority
- &ModAuthority
- &DelAuthority
- &GetAuthority
- &GetAuthorityXML
+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
+ &CountUsage
+ &CountUsageChildren
+ &SearchAuthorities
- &BuildSummary
- &BuildUnimarcHierarchies
- &BuildUnimarcHierarchy
+ &BuildSummary
+ &BuildUnimarcHierarchies
+ &BuildUnimarcHierarchy
- &merge
- &FindDuplicateAuthority
- );
+ &merge
+ &FindDuplicateAuthority
+ );
+}
=head2 GetAuthMARCFromKohaField
Comment :
Suppose Kohafield is only linked to ONE subfield
+
=back
=cut
+
sub GetAuthMARCFromKohaField {
#AUTHfind_marc_from_kohafield
my ( $kohafield,$authtypecode ) = @_;
=back
=cut
+
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";
$result{$title.$authid}=$authid;
}
# sort the hash and return the same structure as GetRecords (Zebra querying)
- my @finalresult = ();
+ my @listresult = ();
my $numbers=0;
if ($sortby eq 'HeadingDsc') { # sort by mainmainentry desc
foreach my $key (sort {$b cmp $a} (keys %result)) {
- push @finalresult, $result{$key};
+ push @listresult, $result{$key};
# warn "push..."$#finalresult;
$numbers++;
}
} else { # sort by mainmainentry ASC
foreach my $key (sort (keys %result)) {
- push @finalresult, $result{$key};
+ push @listresult, $result{$key};
# warn "push..."$#finalresult;
$numbers++;
}
}
# limit the $results_per_page to result size if it's more
- $length = $numbers-1 if $numbers < $length;
+ $length = $numbers-$offset if $numbers < ($offset+$length);
# for the requested page, replace authid by the complete record
# speed improvement : avoid reading too much things
- for (my $counter=$offset;$counter<=$offset+$length;$counter++) {
+ 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 = MARC::File::USMARC::decode(GetAuthority($finalresult[$counter])->as_usmarc);
- my $authid=$authrecord->field('001')->data();
+ 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);
$newline{summary} = $summary;
$newline{authid} = $authid;
$newline{even} = $counter % 2;
- $finalresult[$counter]= \%newline;
+ push @finalresult, \%newline;
}
return (\@finalresult, $numbers);
} else {
my @authtypecode;
my @auths=split / /,$authtypecode ;
foreach my $auth (@auths){
- $query .=" \@attr 1=Authority/format-id \@attr 5=100 ".$auth; ##No truncation on authtype
+ $query .=" \@attr 1=authtype \@attr 5=100 ".$auth; ##No truncation on authtype
push @authtypecode ,$auth;
$n++;
}
if ($n>1){
- $query= "\@or ".$query;
+ while ($n>1){$query= "\@or ".$query;$n--;}
}
my $dosearch;
if (@$value[$i]){
##If mainentry search $a tag
if (@$tags[$i] eq "mainmainentry") {
- $attr =" \@attr 1=Heading ";
+ $attr =" \@attr 1=Heading-Main ";
}elsif (@$tags[$i] eq "mainentry") {
- $attr =" \@attr 1=Heading-Entity ";
+ $attr =" \@attr 1=Heading ";
}else{
$attr =" \@attr 1=Any ";
}
}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
+ $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
}
}#if value
}
##Add how many queries generated
- $query= $and.$query.$q2;
+ if ($query=~/\S+/){
+ $query= $and.$query.$q2
+ } else {
+ $query=$q2;
+ }
## Adding order
- $query=' @or @attr 7=1 @attr 1=Heading 0 @or @attr 7=1 @attr 1=Heading-Entity 1'.$query if ($sortby eq "HeadingAsc");
- $query=' @or @attr 7=2 @attr 1=Heading 0 @or @attr 7=1 @attr 1=Heading-Entity 1'.$query if ($sortby eq "HeadingDsc");
+ #$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=($query?"\@or $orderstring $query":"\@or \@attr 1=_ALLRECORDS \@attr 2=103 '' $orderstring ");
$offset=0 unless $offset;
my $counter = $offset;
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
=back
=cut
+
sub CountUsageChildren {
my ($authid) = @_;
}
=back
=cut
+
sub GetAuthTypeCode {
#AUTHfind_authtypecode
my ($authid) = @_;
=back
=cut
+
sub GetTagsLabels {
my ($forlibrarian,$authtypecode)= @_;
my $dbh=C4::Context->dbh;
# 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"
$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"
=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 $leader=' a ';##Fixme correct leader as this one just adds utf8 to MARC21
# 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 "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);
+ }
+
+ unless ($record->field($auth_type_tag) && $record->subfield($auth_type_tag, $auth_type_subfield)) {
+ $record->add_fields($auth_type_tag,'','', $auth_type_subfield=>$authtypecode);
+ }
+
+ 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');
+ 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));
+ }
# warn $record->as_formatted;
- $dbh->do("lock tables auth_header WRITE");
$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);
+ $sth->execute($authid,$authtypecode,$record->as_usmarc,$record->as_xml_record($format));
$sth->finish;
}else{
+ if (C4::Context->preference('NoZebra')) {
+ $oldRecord = GetAuthority($authid);
+ }
$record->add_fields('001',$authid) unless ($record->field('001'));
- $record->add_fields('100',$authid) unless ($record->field('100'));
- $record->add_fields('152','','','b'=>$authtypecode) unless ($record->field('152'));
- $dbh->do("lock tables auth_header WRITE");
my $sth=$dbh->prepare("update auth_header set marc=?,marcxml=? where authid=?");
- $sth->execute($record->as_usmarc,$record->as_xml_record,$authid);
+ $sth->execute($record->as_usmarc,$record->as_xml_record($format),$authid);
$sth->finish;
+ $dbh->do("unlock tables");
}
- $dbh->do("unlock tables");
- ModZebra($authid,'specialUpdate',"authorityserver",$record);
+ ModZebra($authid,'specialUpdate',"authorityserver",$oldRecord,$record);
return ($authid);
}
my ($authid) = @_;
my $dbh=C4::Context->dbh;
- ModZebra($authid,"recordDelete","authorityserver",GetAuthority($authid));
+ ModZebra($authid,"recordDelete","authorityserver",GetAuthority($authid),undef);
$dbh->do("delete from auth_header where authid=$authid") ;
}
sub ModAuthority {
my ($authid,$record,$authtypecode,$merge)=@_;
my $dbh=C4::Context->dbh;
-# my ($oldrecord)=&GetAuthority($authid);
-# if ($oldrecord eq $record) {
-# return;
-# }
-# my $sth=$dbh->prepare("update auth_header set marc=?,marcxml=? where authid=?");
#Now rewrite the $record to table with an add
+ my $oldrecord=GetAuthority($authid);
$authid=AddAuthority($record,$authid,$authtypecode);
### 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('dontmerge') ){
- # save the file in localfile/modified_authorities
+ # 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."/localfile/modified_authorities/$authid.authid";
+ my $filename = $cgidir."/tmp/modified_authorities/$authid.authid";
open AUTH, "> $filename";
print AUTH $authid;
close AUTH;
} else {
-# &merge($authid,$record,$authid,$record);
+ &merge($authid,$oldrecord,$authid,$record);
}
return $authid;
}
=back
=cut
+
sub GetAuthorityXML {
# Returns MARC::XML of the authority passed in parameter.
my ( $authid ) = @_;
- 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;
-
+ 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") {
+ # 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($format);
+ } else {
+ 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;
+ }
}
=head2 GetAuthority
=back
=cut
+
sub GetAuthority {
my ($authid)=@_;
my $dbh=C4::Context->dbh;
- my $sth=$dbh->prepare("select marcxml from auth_header where authid=?");
+ my $sth=$dbh->prepare("select authtypecode, marcxml from auth_header where authid=?");
$sth->execute($authid);
- my ($marcxml) = $sth->fetchrow;
- my $record=MARC::Record->new_from_xml($marcxml,'UTF-8',(C4::Context->preference("marcflavour") eq "UNIMARC"?"UNIMARCAUTH":C4::Context->preference("marcflavour")));
+ my ($authtypecode, $marcxml) = $sth->fetchrow;
+ my $record=eval {MARC::Record->new_from_xml(StripNonXmlChars($marcxml),'UTF-8',
+ (C4::Context->preference("marcflavour") eq "UNIMARC"?"UNIMARCAUTH":C4::Context->preference("marcflavour")))};
+ return undef if ($@);
$record->encoding('UTF-8');
+ if (C4::Context->preference("marcflavour") eq "MARC21") {
+ my ($auth_type_tag, $auth_type_subfield) = get_auth_type_location($authtypecode);
+ C4::AuthoritiesMarc::MARC21::fix_marc21_auth_type_location($record, $auth_type_tag, $auth_type_subfield);
+ }
return ($record);
}
=over 4
-$result= &GetAuthType( $authtypecode)
-If $authtypecode is not "" then
- Returns hashref to authtypecode information
-else
- returns ref to array of hashref information of all Authtypes
+$result = &GetAuthType($authtypecode)
=back
+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.
+
=cut
+
sub GetAuthType {
my ($authtypecode) = @_;
my $dbh=C4::Context->dbh;
my $sth;
- if ($authtypecode){
- $sth=$dbh->prepare("select * from auth_types where authtypecode=?");
- $sth->execute($authtypecode);
- } else {
- $sth=$dbh->prepare("select * from auth_types");
- $sth->execute;
- }
- my $res=$sth->fetchall_arrayref({});
- if (scalar(@$res)==1){
- return $res->[0];
- } else {
- return $res;
+ 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;
}
# 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 ($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]);
## give this a Marc record to return summary
my ($record,$authid,$authtypecode)=@_;
my $dbh=C4::Context->dbh;
- my $authref = GetAuthType($authtypecode);
- my $summary = $authref->{summary};
+ 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";
my @fields = $record->fields();
my $reported_tag;
# if the library has a summary defined, use it. Otherwise, build a standard one
- if ($summary) {
+ # 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) {
$summary.= '<p><div class="label">'.$seeheading.'</div></p>' 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')) {
}
} #See From
foreach my $field ($record->field('4..')) {
- $seeheading.= " ".$field->as_string()."<br />";
- $seeheading.= " <i>see:</i> ".$seeheading."<br />";
+ $seeheading.= "<br /> <i>used for/see from:</i> ".$field->as_string();
} #See Also
foreach my $field ($record->field('5..')) {
- $altheading.= " <i>see also:</i> ".$field->as_string()."<br />";
- $altheading.= " ".$field->as_string()."<br />";
- $altheading.= " <i>see also:</i> ".$altheading."<br />";
+ $altheading.= "<br /> <i>see also:</i> ".$field->as_string();
}
+ $summary .= ": " if $summary;
$summary.=$heading.$seeheading.$altheading;
}
}
=back
=cut
+
sub BuildUnimarcHierarchies{
my $authid = shift @_;
# warn "authid : $authid";
=back
=cut
+
sub BuildUnimarcHierarchy{
my $record = shift @_;
my $class = shift @_;
=back
=cut
+
sub GetHeaderAuthority{
my $authid = shift @_;
my $sql= "SELECT * from auth_header WHERE authid = ?";
=back
=cut
+
sub merge {
my ($mergefrom,$MARCfrom,$mergeto,$MARCto) = @_;
+ my ($counteditedbiblio,$countunmodifiedbiblio,$counterrors)=(0,0,0);
my $dbh=C4::Context->dbh;
my $authtypecodefrom = GetAuthTypeCode($mergefrom);
my $authtypecodeto = GetAuthTypeCode($mergeto);
# return if authority does not exist
my @X = $MARCfrom->fields();
- return if $#X == -1;
+ return "error MARCFROM not a marcrecord ".Data::Dumper::Dumper($MARCfrom) if $#X == -1;
@X = $MARCto->fields();
- return if $#X == -1;
+ return "error MARCTO not a marcrecord".Data::Dumper::Dumper($MARCto) if $#X == -1;
# search the tag to report
my $sth = $dbh->prepare("select auth_tag_to_report from auth_types where authtypecode=?");
$sth->execute($authtypecodefrom);
my @record_from;
@record_from = $MARCfrom->field($auth_tag_to_report)->subfields() if $MARCfrom->field($auth_tag_to_report);
+ my @reccache;
# search all biblio tags using this authority.
- $sth = $dbh->prepare("select distinct tagfield from marc_subfield_structure where authtypecode=?");
- $sth->execute($authtypecodefrom);
- my @tags_using_authtype;
- while (my ($tagfield) = $sth->fetchrow) {
- push @tags_using_authtype,$tagfield."9" ;
- }
-
+ #Getting marcbiblios impacted by the change.
if (C4::Context->preference('NoZebra')) {
- warn "MERGE TO DO";
+ #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;
+ map {
+ my $biblionumber=$1 if ($_=~/(\d+),.*/);
+ my $marc=GetMarcBiblio($biblionumber);
+ push @reccache,$marc;
+ } @biblionumbers;
+ }
} else {
- # now, find every biblio using this authority
- my $oConnection=C4::Context->Zconn("biblioserver");
+ #zebra connection
+ my $oConnection=C4::Context->Zconn("biblioserver",0);
+ $oConnection->option("preferredRecordSyntax"=>"XML");
my $query;
- $query= "an= ".$mergefrom;
+ $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 $rec;
+ $rec=$oResult->record($z);
my $marcdata = $rec->raw();
- push @reccache, $marcdata;
+ 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);
+ $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;
+ while (my ($tagfield) = $sth->fetchrow) {
+ push @tags_using_authtype,$tagfield ;
+ }
+ 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) {
- # warn "$subfield,$subfield->[0],$subfield->[1]";
- $tag->update($subfield->[0] =>$subfield->[1]);
- }#for $subfield
+ $field_to->add_subfields($subfield->[0] =>$subfield->[1]);
}
- $marcrecord->delete_field($tag);
- $marcrecord->add_fields($tag);
+ $marcrecord->delete_field($field);
+ $marcrecord->insert_grouped_field($field_to);
$update=1;
+ }
}#for each tag
- }#foreach tagfield
- my $oldbiblio = TransformMarcToKoha($dbh,$marcrecord,"") ;
- if ($update==1){
- &ModBiblio($marcrecord,$oldbiblio->{'biblionumber'},GetFrameworkCode($oldbiblio->{'biblionumber'})) ;
- }
-
- }#foreach $marc
- }
+ }#foreach tagfield
+ my ($bibliotag,$bibliosubf) = GetMarcFromKohaField("biblio.biblionumber","") ;
+ my $biblionumber=$marcrecord->subfield($bibliotag,$bibliosubf);
+ 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;
#
# }#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<auth_header.authtypecode>; 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 <info@koha.org>
=cut
-# $Id$
-# $Log$
-# Revision 1.50 2007/07/26 15:14:05 toins
-# removing warn compilation.
-#
-# Revision 1.49 2007/07/16 15:45:28 hdl
-# Adding Summary for UNIMARC authorities
-#
-# Revision 1.48 2007/06/25 15:01:45 tipaul
-# bugfixes on unimarc 100 handling (the field used for encoding)
-#
-# Revision 1.47 2007/06/06 13:08:35 tipaul
-# bugfixes (various), handling utf-8 without guessencoding (as suggested by joshua, fixing some zebra config files -for french but should be interesting for other languages-
-#
-# Revision 1.46 2007/05/10 14:45:15 tipaul
-# Koha NoZebra :
-# - support for authorities
-# - some bugfixes in ordering and "CCL" parsing
-# - support for authorities <=> biblios walking
-#
-# Seems I can do what I want now, so I consider its done, except for bugfixes that will be needed i m sure !
-#
-# Revision 1.45 2007/04/06 14:48:45 hdl
-# Code Cleaning : AuthoritiesMARC.
-#
-# Revision 1.44 2007/04/05 12:17:55 btoumi
-# add "sort by" with heading-entity in authorities search
-#
-# Revision 1.43 2007/03/30 11:59:16 tipaul
-# some cleaning (minor, the main one will come later) : removing some unused subs
-#
-# Revision 1.42 2007/03/29 16:45:53 tipaul
-# Code cleaning of Biblio.pm (continued)
-#
-# All subs have be cleaned :
-# - removed useless
-# - merged some
-# - reordering Biblio.pm completly
-# - using only naming conventions
-#
-# Seems to have broken nothing, but it still has to be heavily tested.
-# Note that Biblio.pm is now much more efficient than previously & probably more reliable as well.
-#
-# 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 TransformKohaToMarc+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 SearchAuthorities
-# + 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 : CountUsage 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.