1 package C4::AuthoritiesMarc;
2 # Copyright 2000-2002 Katipo Communications
4 # This file is part of Koha.
6 # Koha is free software; you can redistribute it and/or modify it under the
7 # terms of the GNU General Public License as published by the Free Software
8 # Foundation; either version 2 of the License, or (at your option) any later
11 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
12 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License along with
16 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
17 # Suite 330, Boston, MA 02111-1307 USA
27 use vars qw($VERSION @ISA @EXPORT);
29 # set the version for version checking
36 &AUTHfind_authtypecode
52 &MARCaddword &MARCdelword
58 my ($dbh, $tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode) = @_;
59 # build the sql request. She will look like :
61 # from auth_subfield_table as m1, auth_subfield_table as m2
62 # where m1.authid=m2.authid and
63 # (m1.subfieldvalue like "Des%" and m2.subfieldvalue like "27%")
65 # the marclist may contain "mainentry". In this case, search the tag_to_report, that depends on
66 # the authtypecode. Then, search on $a of this tag_to_report
67 # also store main entry MARC tag, to extract it at end of search
69 my $sth = $dbh->prepare("select auth_tag_to_report from auth_types where authtypecode=?");
70 $sth->execute($authtypecode);
71 my ($tag_to_report) = $sth->fetchrow;
72 $mainentrytag = $tag_to_report;
73 for (my $i=0;$i<$#{$tags};$i++) {
74 if (@$tags[$i] eq "mainentry") {
75 @$tags[$i] = $tag_to_report."a";
80 # quote marc fields/subfields
81 for (my $i=0;$i<=$#{$tags};$i++) {
83 @$tags[$i] = $dbh->quote(@$tags[$i]);
87 my @normal_and_or = ();
88 my @normal_operator = ();
89 my @normal_value = ();
90 # Extracts the NOT statements from the list of statements
91 for(my $i = 0 ; $i <= $#{$value} ; $i++)
94 @$value[$i] =~ s/\*/%/g;
95 # remove % at the beginning
96 @$value[$i] =~ s/^%//g;
97 @$value[$i] =~ s/(\.|\?|\:|\!|\'|,|\-|\"|\(|\)|\[|\]|\{|\}|\/)/ /g if @$operator[$i] eq "contains";
98 if(@$operator[$i] eq "contains") # if operator is contains, splits the words in separate requests
100 foreach my $word (split(/ /, @$value[$i]))
102 unless (C4::Context->stopwords->{uc($word)}) { #it's NOT a stopword => use it. Otherwise, ignore
103 my $tag = substr(@$tags[$i],0,3);
104 my $subf = substr(@$tags[$i],3,1);
105 push @normal_tags, @$tags[$i];
106 push @normal_and_or, "and"; # assumes "foo" and "bar" if "foo bar" is entered
107 push @normal_operator, @$operator[$i];
108 push @normal_value, $word;
114 push @normal_tags, @$tags[$i];
115 push @normal_and_or, @$and_or[$i];
116 push @normal_operator, @$operator[$i];
117 push @normal_value, @$value[$i];
121 # Finds the basic results without the NOT requests
122 my ($sql_tables, $sql_where1, $sql_where2) = create_request($dbh,\@normal_tags, \@normal_and_or, \@normal_operator, \@normal_value);
127 $sth = $dbh->prepare("select distinct m1.authid from auth_header,$sql_tables where m1.authid=auth_header.authid and auth_header.authtypecode=? and $sql_where2 and ($sql_where1)");
128 warn "Q2 : select distinct m1.authid from auth_header,$sql_tables where m1.authid=auth_header.authid and auth_header.authtypecode=? and $sql_where2 and ($sql_where1)";
130 $sth = $dbh->prepare("select distinct m1.authid from auth_header,$sql_tables where m1.authid=auth_header.authid and auth_header.authtypecode=? and $sql_where1");
131 warn "Q : select distinct m1.authid from auth_header,$sql_tables where m1.authid=auth_header.authid and auth_header.authtypecode=? and $sql_where1";
133 $sth->execute($authtypecode);
135 while (my ($authid) = $sth->fetchrow) {
136 push @result,$authid;
138 # we have authid list. Now, loads summary from [offset] to [offset]+[length]
139 # my $counter = $offset;
140 my @finalresult = ();
142 # while (($counter <= $#result) && ($counter <= ($offset + $length))) {
143 # retrieve everything
144 for (my $counter=0;$counter <=$#result;$counter++) {
145 # warn " HERE : $counter, $#result, $offset, $length";
146 # get MARC::Record of the authority
147 my $record = AUTHgetauthority($dbh,$result[$counter]);
148 # then build the summary
149 my $authtypecode = AUTHfind_authtypecode($dbh,$result[$counter]);
150 my $authref = getauthtype($authtypecode);
151 my $summary = $authref->{summary};
152 my @fields = $record->fields();
153 foreach my $field (@fields) {
154 my $tag = $field->tag();
157 my @subf = $field->subfields;
158 for my $i (0..$#subf) {
159 my $subfieldcode = $subf[$i][0];
160 my $subfieldvalue = $subf[$i][1];
161 my $tagsubf = $tag.$subfieldcode;
162 $summary =~ s/\[(.?.?.?.?)$tagsubf(.*?)]/$1$subfieldvalue$2\[$1$tagsubf$2]/g;
166 $summary =~ s/\[(.*?)]//g;
167 $summary =~ s/\n/<br>/g;
169 # find biblio MARC field using this authtypecode (to jump to biblio)
170 $authtypecode = AUTHfind_authtypecode($dbh,$result[$counter]);
171 my $sth = $dbh->prepare("select distinct tagfield from marc_subfield_structure where authtypecode=?");
172 $sth->execute($authtypecode);
173 my $tags_using_authtype;
174 while (my ($tagfield) = $sth->fetchrow) {
175 # warn "TAG : $tagfield";
176 $tags_using_authtype.= $tagfield."9,";
178 chop $tags_using_authtype;
180 # then add a line for the template loop
182 $newline{summary} = $summary;
183 $newline{authid} = $result[$counter];
184 $newline{used} = &AUTHcount_usage($result[$counter]);
185 $newline{biblio_fields} = $tags_using_authtype;
186 $newline{even} = $counter % 2;
187 $newline{mainentry} = $record->field($mainentrytag)->subfield('a')." ".$record->field($mainentrytag)->subfield('b') if $record->field($mainentrytag);
188 push @finalresult, \%newline;
191 my @finalresult3= sort {$a->{summary} cmp $b->{summary}} @finalresult;
192 # cut from $offset to $offset+$length;
194 for (my $i=$offset;$i<=$offset+$length;$i++) {
195 push @finalresult2,$finalresult3[$i] if $finalresult3[$i];
197 my $nbresults = $#result + 1;
199 return (\@finalresult2, $nbresults);
202 # Creates the SQL Request
205 my ($dbh,$tags, $and_or, $operator, $value) = @_;
207 my $sql_tables; # will contain marc_subfield_table as m1,...
208 my $sql_where1; # will contain the "true" where
209 my $sql_where2 = "("; # will contain m1.authid=m2.authid
210 my $nb_active=0; # will contain the number of "active" entries. and entry is active is a value is provided.
211 my $nb_table=1; # will contain the number of table. ++ on each entry EXCEPT when an OR is provided.
214 for(my $i=0; $i<=@$value;$i++) {
217 # warn " @$tags[$i]";
219 if (@$operator[$i] eq "start") {
220 $sql_tables .= "auth_subfield_table as m$nb_table,";
221 $sql_where1 .= "(m1.subfieldvalue like ".$dbh->quote("@$value[$i]%");
223 $sql_where1 .=" and m1.tag+m1.subfieldcode in (@$tags[$i])";
226 } elsif (@$operator[$i] eq "contains") {
227 $sql_tables .= "auth_word as m$nb_table,";
228 $sql_where1 .= "(m1.word like ".$dbh->quote("@$value[$i]%");
230 $sql_where1 .=" and m1.tagsubfield in (@$tags[$i])";
235 $sql_tables .= "auth_subfield_table as m$nb_table,";
236 $sql_where1 .= "(m1.subfieldvalue @$operator[$i] ".$dbh->quote("@$value[$i]");
238 $sql_where1 .=" and m1.tag+m1.subfieldcode in (@$tags[$i])";
243 if (@$operator[$i] eq "start") {
245 $sql_tables .= "auth_subfield_table as m$nb_table,";
246 $sql_where1 .= "@$and_or[$i] (m$nb_table.subfieldvalue like ".$dbh->quote("@$value[$i]%");
248 $sql_where1 .=" and m$nb_table.tag+m$nb_table.subfieldcode in (@$tags[$i])";
251 $sql_where2 .= "m1.authid=m$nb_table.authid and ";
252 } elsif (@$operator[$i] eq "contains") {
253 if (@$and_or[$i] eq 'and') {
255 $sql_tables .= "auth_word as m$nb_table,";
256 $sql_where1 .= "@$and_or[$i] (m$nb_table.word like ".$dbh->quote("@$value[$i]%");
258 $sql_where1 .=" and m$nb_table.tagsubfield in(@$tags[$i])";
261 $sql_where2 .= "m1.authid=m$nb_table.authid and ";
263 $sql_where1 .= "@$and_or[$i] (m$nb_table.word like ".$dbh->quote("@$value[$i]%");
265 $sql_where1 .=" and m$nb_table.tag+m$nb_table.subfieldid in (@$tags[$i])";
268 $sql_where2 .= "m1.authid=m$nb_table.authid and ";
272 $sql_tables .= "auth_subfield_table as m$nb_table,";
273 $sql_where1 .= "@$and_or[$i] (m$nb_table.subfieldvalue @$operator[$i] ".$dbh->quote(@$value[$i]);
275 $sql_where1 .=" and m$nb_table.tag+m$nb_table.subfieldcode in (@$tags[$i])";
277 $sql_where2 .= "m1.authid=m$nb_table.authid and ";
284 if($sql_where2 ne "(") # some datas added to sql_where2, processing
286 $sql_where2 = substr($sql_where2, 0, (length($sql_where2)-5)); # deletes the trailing ' and '
289 else # no sql_where2 statement, deleting '('
293 chop $sql_tables; # deletes the trailing ','
295 return ($sql_tables, $sql_where1, $sql_where2);
299 sub AUTHcount_usage {
301 my $dbh = C4::Context->dbh;
302 # find MARC fields using this authtype
303 my $authtypecode = AUTHfind_authtypecode($dbh,$authid);
304 my $sth = $dbh->prepare("select distinct tagfield from marc_subfield_structure where authtypecode=?");
305 $sth->execute($authtypecode);
306 my $tags_using_authtype;
307 while (my ($tagfield) = $sth->fetchrow) {
308 # warn "TAG : $tagfield";
309 $tags_using_authtype.= "'".$tagfield."9',";
311 chop $tags_using_authtype;
312 if ($tags_using_authtype) {
313 $sth = $dbh->prepare("select count(*) from marc_subfield_table where concat(tag,subfieldcode) in ($tags_using_authtype) and subfieldvalue=?");
315 # $sth = $dbh->prepare("select count(*) from marc_subfield_table where subfieldvalue=?");
317 # warn "Q : select count(*) from marc_subfield_table where concat(tag,subfieldcode) in ($tags_using_authtype) and subfieldvalue=$authid";
318 $sth->execute($authid);
319 my ($result) = $sth->fetchrow;
320 # warn "Authority $authid TOTAL USED : $result";
324 # merging 2 authority entries. After a merge, the "from" can be deleted.
326 # my ($auth_merge_from,$auth_merge_to) = @_;
327 # my $dbh = C4::Context->dbh;
328 # # find MARC fields using this authtype
329 # my $authtypecode = AUTHfind_authtypecode($dbh,$authid);
331 # my $record_from = AUTHgetauthority($dbh,$auth_merge_from);
332 # my $record_to = AUTHgetauthority($dbh,$auth_merge_to);
333 # my $sth = $dbh->prepare("select distinct tagfield from marc_subfield_structure where authtypecode=?");
334 # $sth->execute($authtypecode);
335 # my $tags_using_authtype;
336 # while (my ($tagfield) = $sth->fetchrow) {
337 # warn "TAG : $tagfield";
338 # $tags_using_authtype.= "'".$tagfield."9',";
340 # chop $tags_using_authtype;
341 # # now, find every biblio using this authority
342 # $sth = $dbh->prepare("select bibid,tag,tag_indicator,tagorder from marc_subfield_table where tag+subfieldid in ($tags_using_authtype) and subfieldvalue=?");
343 # $sth->execute($authid);
344 # # and delete entries before recreating them
345 # while (my ($bibid,$tag,$tag_indicator,$tagorder) = $sth->fetchrow) {
346 # &MARCdelsubfield($dbh,$bibid,$tag);
352 sub AUTHfind_authtypecode {
353 my ($dbh,$authid) = @_;
354 my $sth = $dbh->prepare("select authtypecode from auth_header where authid=?");
355 $sth->execute($authid);
356 my ($authtypecode) = $sth->fetchrow;
357 return $authtypecode;
362 my ($dbh,$forlibrarian,$authtypecode)= @_;
363 $authtypecode="" unless $authtypecode;
365 my $libfield = ($forlibrarian eq 1)? 'liblibrarian' : 'libopac';
366 # check that framework exists
367 $sth=$dbh->prepare("select count(*) from auth_tag_structure where authtypecode=?");
368 $sth->execute($authtypecode);
369 my ($total) = $sth->fetchrow;
370 $authtypecode="" unless ($total >0);
371 $sth=$dbh->prepare("select tagfield,$libfield as lib,mandatory,repeatable from auth_tag_structure where authtypecode=? order by tagfield");
372 $sth->execute($authtypecode);
373 my ($lib,$tag,$res,$tab,$mandatory,$repeatable);
374 while ( ($tag,$lib,$mandatory,$repeatable) = $sth->fetchrow) {
375 $res->{$tag}->{lib}=$lib;
376 $res->{$tab}->{tab}=""; # XXX
377 $res->{$tag}->{mandatory}=$mandatory;
378 $res->{$tag}->{repeatable}=$repeatable;
381 $sth=$dbh->prepare("select tagfield,tagsubfield,$libfield as lib,tab, mandatory, repeatable,authorised_value,value_builder,seealso from auth_subfield_structure where authtypecode=? order by tagfield,tagsubfield");
382 $sth->execute($authtypecode);
385 my $authorised_value;
386 my $thesaurus_category;
392 while ( ($tag, $subfield, $lib, $tab, $mandatory, $repeatable,$authorised_value,$value_builder,$seealso) = $sth->fetchrow) {
393 $res->{$tag}->{$subfield}->{lib}=$lib;
394 $res->{$tag}->{$subfield}->{tab}=$tab;
395 $res->{$tag}->{$subfield}->{mandatory}=$mandatory;
396 $res->{$tag}->{$subfield}->{repeatable}=$repeatable;
397 $res->{$tag}->{$subfield}->{authorised_value}=$authorised_value;
398 $res->{$tag}->{$subfield}->{thesaurus_category}=$thesaurus_category;
399 $res->{$tag}->{$subfield}->{value_builder}=$value_builder;
400 $res->{$tag}->{$subfield}->{seealso}=$seealso;
401 $res->{$tag}->{$subfield}->{hidden}=$hidden;
402 $res->{$tag}->{$subfield}->{isurl}=$isurl;
407 sub AUTHaddauthority {
408 # pass the MARC::Record to this function, and it will create the records in the marc tables
409 my ($dbh,$record,$authid,$authtypecode) = @_;
410 my @fields=$record->fields();
411 # adding main table, and retrieving authid
412 # if authid is sent, then it's not a true add, it's only a re-add, after a delete (ie, a mod)
413 # if authid empty => true add, find a new authid number
415 $dbh->do("lock tables auth_header WRITE,auth_subfield_table WRITE, auth_word WRITE, stopwords READ");
416 my $sth=$dbh->prepare("insert into auth_header (datecreated,authtypecode) values (now(),?)");
417 $sth->execute($authtypecode);
418 $sth=$dbh->prepare("select max(authid) from auth_header");
420 ($authid)=$sth->fetchrow;
424 # now, add subfields...
425 foreach my $field (@fields) {
427 if ($field->tag() <10) {
428 &AUTHaddsubfield($dbh,$authid,
437 my @subfields=$field->subfields();
439 foreach my $subfield (@subfields) {
440 foreach (split /\|/,@$subfield[1]) {
442 &AUTHaddsubfield($dbh,$authid,
444 $field->indicator(1).$field->indicator(2),
454 $dbh->do("unlock tables");
459 sub AUTHaddsubfield {
460 # Add a new subfield to a tag into the DB.
461 my ($dbh,$authid,$tagid,$tag_indicator,$tagorder,$subfieldcode,$subfieldorder,$subfieldvalues) = @_;
462 # if not value, end of job, we do nothing
463 if (length($subfieldvalues) ==0) {
466 if (not($subfieldcode)) {
469 my @subfieldvalues = split /\|/,$subfieldvalues;
470 foreach my $subfieldvalue (@subfieldvalues) {
471 my $sth=$dbh->prepare("insert into auth_subfield_table (authid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue) values (?,?,?,?,?,?,?)");
472 # warn "==> $authid,".(sprintf "%03s",$tagid).",TAG : $tagorder,$tag_indicator,$subfieldcode,$subfieldorder,$subfieldvalue";
473 $sth->execute($authid,(sprintf "%03s",$tagid),$tagorder,$tag_indicator,$subfieldcode,$subfieldorder,$subfieldvalue);
475 warn "ERROR ==> insert into auth_subfield_table (authid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue) values ($authid,$tagid,$tagorder,$tag_indicator,$subfieldcode,$subfieldorder,$subfieldvalue)\n";
477 &AUTHaddword($dbh,$authid,$tagid,$tagorder,$subfieldcode,$subfieldorder,$subfieldvalue);
481 sub AUTHgetauthority {
482 # Returns MARC::Record of the biblio passed in parameter.
483 my ($dbh,$authid)=@_;
484 my $record = MARC::Record->new();
485 #---- TODO : the leader is missing
486 $record->leader(' ');
487 my $sth=$dbh->prepare("select authid,subfieldid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue
488 from auth_subfield_table
489 where authid=? order by tag,tagorder,subfieldorder
491 $sth->execute($authid);
495 my $field; # for >=10 tags
496 my $prevvalue; # for <10 tags
497 while (my $row=$sth->fetchrow_hashref) {
498 if ($row->{tagorder} ne $prevtagorder || $row->{tag} ne $prevtag) {
501 $record->add_fields((sprintf "%03s",$prevtag),$prevvalue) unless $prevtag eq "XXX"; # ignore the 1st loop
503 $record->add_fields($field) unless $prevtag eq "XXX";
506 $prevtagorder=$row->{tagorder};
507 $prevtag = $row->{tag};
508 $previndicator=$row->{tag_indicator};
509 if ($row->{tag}<10) {
510 $prevvalue = $row->{subfieldvalue};
512 $field = MARC::Field->new((sprintf "%03s",$prevtag), substr($row->{tag_indicator}.' ',0,1), substr($row->{tag_indicator}.' ',1,1), $row->{'subfieldcode'}, $row->{'subfieldvalue'} );
515 if ($row->{tag} <10) {
516 $record->add_fields((sprintf "%03s",$row->{tag}), $row->{'subfieldvalue'});
518 $field->add_subfields($row->{'subfieldcode'}, $row->{'subfieldvalue'} );
520 $prevtag= $row->{tag};
521 $previndicator=$row->{tag_indicator};
524 # the last has not been included inside the loop... do it now !
525 if ($prevtag ne "XXX") { # check that we have found something. Otherwise, prevtag is still XXX and we
526 # must return an empty record, not make MARC::Record fail because we try to
527 # create a record with XXX as field :-(
529 $record->add_fields($prevtag,$prevvalue);
531 # my $field = MARC::Field->new( $prevtag, "", "", %subfieldlist);
532 $record->add_fields($field);
538 sub AUTHgetauth_type {
539 my ($authtypecode) = @_;
540 my $dbh=C4::Context->dbh;
541 my $sth=$dbh->prepare("select * from auth_types where authtypecode=?");
542 $sth->execute($authtypecode);
543 return $sth->fetchrow_hashref;
545 sub AUTHmodauthority {
546 my ($dbh,$authid,$record,$delete)=@_;
547 my $oldrecord=&AUTHgetauthority($dbh,$authid);
548 if ($oldrecord eq $record) {
551 # 1st delete the authority,
553 &AUTHdelauthority($dbh,$authid,1);
554 &AUTHaddauthority($dbh,$record,$authid,AUTHfind_authtypecode($dbh,$authid));
555 # save the file in localfile/modified_authorities
556 my $cgidir = C4::Context->intranetdir ."/cgi-bin";
557 unless (opendir(DIR, "$cgidir")) {
558 $cgidir = C4::Context->intranetdir."/";
561 my $filename = $cgidir."/localfile/modified_authorities/$authid.authid";
562 open AUTH, "> $filename";
567 sub AUTHdelauthority {
568 my ($dbh,$authid,$keep_biblio) = @_;
569 # if the keep_biblio is set to 1, then authority entries in biblio are preserved.
570 # This flag is set when the delauthority is called by modauthority
571 # due to a too complex structure of MARC (repeatable fields and subfields),
572 # the best solution for a modif is to delete / recreate the record.
574 my $record = AUTHgetauthority($dbh,$authid);
575 $dbh->do("delete from auth_header where authid=$authid") unless $keep_biblio;
576 $dbh->do("delete from auth_subfield_table where authid=$authid");
577 $dbh->do("delete from auth_word where authid=$authid");
578 # FIXME : delete or not in biblio tables (depending on $keep_biblio flag)
581 sub AUTHmodsubfield {
582 # Subroutine changes a subfield value given a subfieldid.
583 my ($dbh, $subfieldid, $subfieldvalue )=@_;
584 $dbh->do("lock tables auth_subfield_table WRITE");
585 my $sth=$dbh->prepare("update auth_subfield_table set subfieldvalue=? where subfieldid=?");
586 $sth->execute($subfieldvalue, $subfieldid);
587 $dbh->do("unlock tables");
589 $sth=$dbh->prepare("select authid,tag,tagorder,subfieldcode,subfieldid,subfieldorder from auth_subfield_table where subfieldid=?");
590 $sth->execute($subfieldid);
591 my ($authid,$tagid,$tagorder,$subfieldcode,$x,$subfieldorder) = $sth->fetchrow;
593 &AUTHdelword($dbh,$authid,$tagid,$tagorder,$subfieldcode,$subfieldorder);
594 &AUTHaddword($dbh,$authid,$tagid,$tagorder,$subfieldcode,$subfieldorder,$subfieldvalue);
595 return($subfieldid, $subfieldvalue);
598 sub AUTHfindsubfield {
599 my ($dbh,$authid,$tag,$subfieldcode,$subfieldorder,$subfieldvalue) = @_;
603 my $query="select subfieldid from auth_subfield_table where authid=? and tag=? and subfieldcode=?";
604 my @bind_values = ($authid,$tag, $subfieldcode);
605 if ($subfieldvalue) {
606 $query .= " and subfieldvalue=?";
607 push(@bind_values,$subfieldvalue);
609 if ($subfieldorder<1) {
612 $query .= " and subfieldorder=?";
613 push(@bind_values,$subfieldorder);
615 my $sti=$dbh->prepare($query);
616 $sti->execute(@bind_values);
617 while (($subfieldid) = $sti->fetchrow) {
619 $lastsubfieldid=$subfieldid;
621 if ($resultcounter>1) {
622 # Error condition. Values given did not resolve into a unique record. Don't know what to edit
623 # should rarely occur (only if we use subfieldvalue with a value that exists twice, which is strange)
626 return $lastsubfieldid;
630 sub AUTHfindsubfieldid {
631 my ($dbh,$authid,$tag,$tagorder,$subfield,$subfieldorder) = @_;
632 my $sth=$dbh->prepare("select subfieldid from auth_subfield_table
633 where authid=? and tag=? and tagorder=?
634 and subfieldcode=? and subfieldorder=?");
635 $sth->execute($authid,$tag,$tagorder,$subfield,$subfieldorder);
636 my ($res) = $sth->fetchrow;
638 $sth=$dbh->prepare("select subfieldid from auth_subfield_table
639 where authid=? and tag=? and tagorder=?
640 and subfieldcode=?");
641 $sth->execute($authid,$tag,$tagorder,$subfield);
642 ($res) = $sth->fetchrow;
647 # sub AUTHfind_authtypecode {
648 # my ($dbh,$authid) = @_;
649 # my $sth = $dbh->prepare("select authtypecode from auth_header where authid=?");
650 # $sth->execute($authid);
651 # my ($authtypecode) = $sth->fetchrow;
652 # return $authtypecode;
655 sub AUTHdelsubfield {
656 # delete a subfield for $authid / tag / tagorder / subfield / subfieldorder
657 my ($dbh,$authid,$tag,$tagorder,$subfield,$subfieldorder) = @_;
658 $dbh->do("delete from auth_subfield_table where authid='$authid' and
659 tag='$tag' and tagorder='$tagorder'
660 and subfieldcode='$subfield' and subfieldorder='$subfieldorder'
665 my ($dbh,$rtags,$rsubfields,$rvalues,%indicators) = @_;
667 my $record = MARC::Record->new();
668 # my %subfieldlist=();
669 my $prevvalue; # if tag <10
670 my $field; # if tag >=10
671 for (my $i=0; $i< @$rtags; $i++) {
672 # rebuild MARC::Record
673 if (@$rtags[$i] ne $prevtag) {
676 $record->add_fields((sprintf "%03s",$prevtag),$prevvalue);
680 $record->add_fields($field);
683 $indicators{@$rtags[$i]}.=' ';
684 if (@$rtags[$i] <10) {
685 $prevvalue= @$rvalues[$i];
689 $field = MARC::Field->new( (sprintf "%03s",@$rtags[$i]), substr($indicators{@$rtags[$i]},0,1),substr($indicators{@$rtags[$i]},1,1), @$rsubfields[$i] => @$rvalues[$i]);
691 $prevtag = @$rtags[$i];
693 if (@$rtags[$i] <10) {
694 $prevvalue=@$rvalues[$i];
696 if (length(@$rvalues[$i])>0) {
697 $field->add_subfields(@$rsubfields[$i] => @$rvalues[$i]);
700 $prevtag= @$rtags[$i];
703 # the last has not been included inside the loop... do it now !
704 $record->add_fields($field) if $field;
709 # split a subfield string and adds it into the word table.
711 my ($dbh,$authid,$tag,$tagorder,$subfieldid,$subfieldorder,$sentence) =@_;
712 $sentence =~ s/(\.|\?|\:|\!|\'|,|\-|\"|\(|\)|\[|\]|\{|\})/ /g;
713 my @words = split / /,$sentence;
714 my $stopwords= C4::Context->stopwords;
715 my $sth=$dbh->prepare("insert into auth_word (authid, tagsubfield, tagorder, subfieldorder, word, sndx_word)
716 values (?,concat(?,?),?,?,?,soundex(?))");
717 foreach my $word (@words) {
718 # we record only words longer than 2 car and not in stopwords hash
719 if (length($word)>2 and !($stopwords->{uc($word)})) {
720 $sth->execute($authid,$tag,$subfieldid,$tagorder,$subfieldorder,$word,$word);
722 warn "ERROR ==> insert into auth_word (authid, tagsubfield, tagorder, subfieldorder, word, sndx_word) values ($authid,concat($tag,$subfieldid),$tagorder,$subfieldorder,$word,soundex($word))\n";
729 # delete words. this sub deletes all the words from a sentence. a subfield modif is done by a delete then a add
730 my ($dbh,$authid,$tag,$tagorder,$subfield,$subfieldorder) = @_;
731 my $sth=$dbh->prepare("delete from auth_word where authid=? and tagsubfield=concat(?,?) and tagorder=? and subfieldorder=?");
732 $sth->execute($authid,$tag,$subfield,$tagorder,$subfieldorder);
736 # converts ISO 5426 coded string to ISO 8859-1
737 # sloppy code : should be improved in next issue
738 my ($string,$encoding) = @_ ;
740 # $encoding = C4::Context->preference("marcflavour") unless $encoding;
741 if ($encoding eq "UNIMARC") {
803 # this handles non-sorting blocks (if implementation requires this)
804 $string = nsb_clean($_) ;
805 } elsif ($encoding eq "USMARC" || $encoding eq "MARC21") {
858 # this handles non-sorting blocks (if implementation requires this)
859 $string = nsb_clean($_) ;
866 my $NSB = '\x88' ; # NSB : begin Non Sorting Block
867 my $NSE = '\x89' ; # NSE : Non Sorting Block end
868 # handles non sorting blocks
872 s/[ ]{0,1}$NSE/) /gm ;
878 my ($record,$authtypecode)=@_;
879 warn "IN for ".$record->as_formatted;
880 my $dbh = C4::Context->dbh;
882 # warn "".$record->as_formatted;
883 my $sth = $dbh->prepare("select auth_tag_to_report,summary from auth_types where authtypecode=?");
884 $sth->execute($authtypecode);
885 my ($auth_tag_to_report,$taglist) = $sth->fetchrow;
887 # build a request for authoritysearch
888 my (@tags, @and_or, @excluding, @operator, @value, $offset, $length);
889 # search on biblio.title
890 # warn " tag a reporter : $auth_tag_to_report";
891 # warn "taglist ".$taglist;
892 my @subfield = split /\[/, $taglist;
894 for (my $i=1; $i<$max;$i++){
895 warn " ".$subfield[$i];
896 $subfield[$i]=substr($subfield[$i],3,1);
897 # warn " ".$subfield[$i];
900 if ($record->fields($auth_tag_to_report)) {
901 my $sth = $dbh->prepare("select tagfield,tagsubfield from auth_subfield_structure where tagfield=? and authtypecode=? ");
902 $sth->execute($auth_tag_to_report,$authtypecode);
903 # warn " field $auth_tag_to_report exists";
904 while (my ($tag,$subfield) = $sth->fetchrow){
905 if ($record->field($tag)->subfield($subfield)) {
906 warn "tag :".$tag." subfield: $subfield value : ".$record->field($tag)->subfield($subfield);
907 push @tags, $tag.$subfield;
908 # warn "'".$tag.$subfield."' value :". $record->field($tag)->subfield($subfield);
912 push @value, $record->field($tag)->subfield($subfield);
917 my ($finalresult,$nbresult) = authoritysearch($dbh,\@tags,\@and_or,\@excluding,\@operator,\@value,0,10,$authtypecode);
918 # there is at least 1 result => return the 1st one
920 warn "XXXXX $nbresult => ".@$finalresult[0]->{authid},@$finalresult[0]->{summary};
921 return @$finalresult[0]->{authid},@$finalresult[0]->{summary};
923 # no result, returns nothing
928 END { } # module clean-up code here (global destructor)
934 Koha Developement team <info@koha.org>
936 Paul POULAIN paul.poulain@free.fr
942 # Revision 1.24 2006/02/09 01:56:20 rangi
943 # Hmm there seem to be quite a few subroutines twice in this module....
945 # Paul could you take a look and remove the ones that shouldnt be there please
947 # Revision 1.23 2006/02/09 01:52:14 rangi
948 # Cleaning up some unessecary my statements
950 # Revision 1.22 2006/01/06 16:39:37 tipaul
951 # synch'ing head and rel_2_2 (from 2.2.5, including npl templates)
952 # Seems not to break too many things, but i'm probably wrong here.
953 # at least, new features/bugfixes from 2.2.5 are here (tested on some features on my head local copy)
955 # - removing useless directories (koha-html and koha-plucene)
957 # Revision 1.21 2005/10/26 09:12:33 tipaul
958 # big commit, still breaking things...
960 # * synch with rel_2_2. Probably the last non manual synch, as rel_2_2 should not be modified deeply.
961 # * code cleaning (cleaning warnings from perl -w) continued
963 # Revision 1.9.2.8 2005/10/25 12:38:59 tipaul
964 # * fixing bug in summary (separator before subfield was in fact after)
965 # * fixing bug in authority order : authorities are not ordered alphabetically instead of no order. Requires all the dataset to be retrieved, but the benefits is important !
967 # Revision 1.9.2.7 2005/08/01 15:14:50 tipaul
968 # minor change in summary handling (accepting 4 digits before the field)
970 # Revision 1.9.2.6 2005/06/07 10:02:00 tipaul
971 # porting dictionnary search from head to 2.2. there is now a ... facing titles, author & subject, to search in biblio & authorities existing values.
973 # Revision 1.9.2.5 2005/05/31 14:50:46 tipaul
974 # fix for authority merging. There was a bug on official installs
976 # Revision 1.9.2.4 2005/05/30 11:24:15 tipaul
977 # 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)
979 # Revision 1.9.2.3 2005/04/28 08:45:33 tipaul
980 # porting FindDuplicate feature for authorities from HEAD to rel_2_2, works correctly now.
982 # Revision 1.9.2.2 2005/02/28 14:03:13 tipaul
983 # * adding search on "main entry" (ie $a subfield) on a given authority (the "search everywhere" field is still here).
984 # * adding a select box to requet "contain" or "begin with" search.
985 # * fixing some bug in authority search (related to "main entry" search)
987 # Revision 1.9.2.1 2005/02/24 13:12:13 tipaul
988 # 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.
989 # So, it will be done through a cron job.
990 # (/me agree we need some doc for command line scripts)
992 # Revision 1.9 2004/12/23 09:48:11 tipaul
993 # Minor changes in summary "exploding" (the 3 digits AFTER the subfield were not on the right place).
995 # Revision 1.8 2004/11/05 10:11:39 tipaul
996 # export auth_count_usage (bugfix)
998 # Revision 1.7 2004/09/23 16:13:00 tipaul
999 # Bugfix in modification
1001 # Revision 1.6 2004/08/18 16:00:24 tipaul
1002 # fixes for authorities management
1004 # Revision 1.5 2004/07/05 13:37:22 doxulting
1005 # First step for working authorities
1007 # Revision 1.4 2004/06/22 11:35:37 tipaul
1008 # removing % at the beginning of a string to avoid loooonnnngggg searchs
1010 # Revision 1.3 2004/06/17 08:02:13 tipaul
1011 # merging tag & subfield in auth_word for better perfs
1013 # Revision 1.2 2004/06/10 08:29:01 tipaul
1014 # MARC authority management (continued)
1016 # Revision 1.1 2004/06/07 07:35:01 tipaul
1017 # MARC authority management package