File: | C4/AuthoritiesMarc.pm |
Coverage: | 4.7% |
line | stmt | bran | cond | sub | time | code |
---|---|---|---|---|---|---|
1 | package C4::AuthoritiesMarc; | |||||
2 | # Copyright 2000-2002 Katipo Communications | |||||
3 | # | |||||
4 | # This file is part of Koha. | |||||
5 | # | |||||
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 | |||||
9 | # version. | |||||
10 | # | |||||
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. | |||||
14 | # | |||||
15 | # You should have received a copy of the GNU General Public License along | |||||
16 | # with Koha; if not, write to the Free Software Foundation, Inc., | |||||
17 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |||||
18 | ||||||
19 | 3 3 3 | 639 30 119 | use strict; | |||
20 | 3 3 3 | 37 25 185 | use warnings; | |||
21 | 3 3 3 | 246 15 59 | use C4::Context; | |||
22 | 3 3 3 | 38297 35562 350 | use MARC::Record; | |||
23 | 3 3 3 | 178 12 1340 | use C4::Biblio; | |||
24 | 3 3 3 | 266 9 462 | use C4::Search; | |||
25 | 3 3 3 | 949 23 95 | use C4::AuthoritiesMarc::MARC21; | |||
26 | 3 3 3 | 485 33 115 | use C4::AuthoritiesMarc::UNIMARC; | |||
27 | 3 3 3 | 33 11 301 | use C4::Charset; | |||
28 | 3 3 3 | 22 10 314 | use C4::Log; | |||
29 | ||||||
30 | 3 3 3 | 20 9 354 | use vars qw($VERSION @ISA @EXPORT); | |||
31 | ||||||
32 | BEGIN { | |||||
33 | # set the version for version checking | |||||
34 | 3 | 13 | $VERSION = 3.01; | |||
35 | ||||||
36 | 3 | 18 | require Exporter; | |||
37 | 3 | 38 | @ISA = qw(Exporter); | |||
38 | 3 | 27658 | @EXPORT = qw( | |||
39 | &GetTagsLabels | |||||
40 | &GetAuthType | |||||
41 | &GetAuthTypeCode | |||||
42 | &GetAuthMARCFromKohaField | |||||
43 | ||||||
44 | &AddAuthority | |||||
45 | &ModAuthority | |||||
46 | &DelAuthority | |||||
47 | &GetAuthority | |||||
48 | &GetAuthorityXML | |||||
49 | ||||||
50 | &CountUsage | |||||
51 | &CountUsageChildren | |||||
52 | &SearchAuthorities | |||||
53 | ||||||
54 | &BuildSummary | |||||
55 | &BuildUnimarcHierarchies | |||||
56 | &BuildUnimarcHierarchy | |||||
57 | ||||||
58 | &merge | |||||
59 | &FindDuplicateAuthority | |||||
60 | ||||||
61 | &GuessAuthTypeCode | |||||
62 | &GuessAuthId | |||||
63 | ); | |||||
64 | } | |||||
65 | ||||||
66 | ||||||
67 - 80 | =head1 NAME C4::AuthoritiesMarc =head2 GetAuthMARCFromKohaField ( $tag, $subfield ) = &GetAuthMARCFromKohaField ($kohafield,$authtypecode); returns tag and subfield linked to kohafield Comment : Suppose Kohafield is only linked to ONE subfield =cut | |||||
81 | ||||||
82 | sub GetAuthMARCFromKohaField { | |||||
83 | #AUTHfind_marc_from_kohafield | |||||
84 | 0 | my ( $kohafield,$authtypecode ) = @_; | ||||
85 | 0 | my $dbh=C4::Context->dbh; | ||||
86 | 0 | return 0, 0 unless $kohafield; | ||||
87 | 0 | $authtypecode="" unless $authtypecode; | ||||
88 | 0 | my $marcfromkohafield; | ||||
89 | 0 | my $sth = $dbh->prepare("select tagfield,tagsubfield from auth_subfield_structure where kohafield= ? and authtypecode=? "); | ||||
90 | 0 | $sth->execute($kohafield,$authtypecode); | ||||
91 | 0 | my ($tagfield,$tagsubfield) = $sth->fetchrow; | ||||
92 | ||||||
93 | 0 | return ($tagfield,$tagsubfield); | ||||
94 | } | |||||
95 | ||||||
96 - 104 | =head2 SearchAuthorities (\@finalresult, $nbresults)= &SearchAuthorities($tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode, $sortby[, $skipmetadata]) returns ref to array result and count of results returned =cut | |||||
105 | ||||||
106 | sub SearchAuthorities { | |||||
107 | 0 | my ($tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode,$sortby,$skipmetadata) = @_; | ||||
108 | # warn Dumper($tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode,$sortby); | |||||
109 | 0 | my $dbh=C4::Context->dbh; | ||||
110 | 0 | if (C4::Context->preference('NoZebra')) { | ||||
111 | ||||||
112 | # | |||||
113 | # build the query | |||||
114 | # | |||||
115 | 0 | my $query; | ||||
116 | 0 | my @auths=split / /,$authtypecode ; | ||||
117 | 0 | foreach my $auth (@auths){ | ||||
118 | 0 | $query .="AND auth_type= $auth "; | ||||
119 | } | |||||
120 | 0 | $query =~ s/^AND //; | ||||
121 | 0 | my $dosearch; | ||||
122 | 0 | for(my $i = 0 ; $i <= $#{$value} ; $i++) | ||||
123 | { | |||||
124 | 0 | if (@$value[$i]){ | ||||
125 | 0 | if (@$tags[$i] =~/mainentry|mainmainentry/) { | ||||
126 | 0 | $query .= qq( AND @$tags[$i] ); | ||||
127 | } else { | |||||
128 | 0 | $query .=" AND "; | ||||
129 | } | |||||
130 | 0 | if (@$operator[$i] eq 'is') { | ||||
131 | 0 | $query.=(@$tags[$i]?"=":""). '"'.@$value[$i].'"'; | ||||
132 | }elsif (@$operator[$i] eq "="){ | |||||
133 | 0 | $query.=(@$tags[$i]?"=":""). '"'.@$value[$i].'"'; | ||||
134 | }elsif (@$operator[$i] eq "start"){ | |||||
135 | 0 | $query.=(@$tags[$i]?"=":"").'"'.@$value[$i].'%"'; | ||||
136 | } else { | |||||
137 | 0 | $query.=(@$tags[$i]?"=":"").'"'.@$value[$i].'%"'; | ||||
138 | } | |||||
139 | 0 | $dosearch=1; | ||||
140 | }#if value | |||||
141 | 0 | } | ||||
142 | # | |||||
143 | # do the query (if we had some search term | |||||
144 | # | |||||
145 | 0 | if ($dosearch) { | ||||
146 | # warn "QUERY : $query"; | |||||
147 | 0 | my $result = C4::Search::NZanalyse($query,'authorityserver'); | ||||
148 | # warn "result : $result"; | |||||
149 | 0 | my %result; | ||||
150 | 0 | foreach (split /;/,$result) { | ||||
151 | 0 | my ($authid,$title) = split /,/,$_; | ||||
152 | # hint : the result is sorted by title.biblionumber because we can have X biblios with the same title | |||||
153 | # and we don't want to get only 1 result for each of them !!! | |||||
154 | # hint & speed improvement : we can order without reading the record | |||||
155 | # so order, and read records only for the requested page ! | |||||
156 | 0 | $result{$title.$authid}=$authid; | ||||
157 | } | |||||
158 | # sort the hash and return the same structure as GetRecords (Zebra querying) | |||||
159 | 0 | my @listresult = (); | ||||
160 | 0 | my $numbers=0; | ||||
161 | 0 | if ($sortby eq 'HeadingDsc') { # sort by mainmainentry desc | ||||
162 | 0 0 | foreach my $key (sort {$b cmp $a} (keys %result)) { | ||||
163 | 0 | push @listresult, $result{$key}; | ||||
164 | # warn "push..."$#finalresult; | |||||
165 | 0 | $numbers++; | ||||
166 | } | |||||
167 | } else { # sort by mainmainentry ASC | |||||
168 | 0 | foreach my $key (sort (keys %result)) { | ||||
169 | 0 | push @listresult, $result{$key}; | ||||
170 | # warn "push..."$#finalresult; | |||||
171 | 0 | $numbers++; | ||||
172 | } | |||||
173 | } | |||||
174 | # limit the $results_per_page to result size if it's more | |||||
175 | 0 | $length = $numbers-$offset if $numbers < ($offset+$length); | ||||
176 | # for the requested page, replace authid by the complete record | |||||
177 | # speed improvement : avoid reading too much things | |||||
178 | 0 | my @finalresult; | ||||
179 | for (my $counter=$offset;$counter<=$offset+$length-1;$counter++) { | |||||
180 | # $finalresult[$counter] = GetAuthority($finalresult[$counter])->as_usmarc; | |||||
181 | 0 | my $separator=C4::Context->preference('authoritysep'); | ||||
182 | 0 | my $authrecord =GetAuthority($listresult[$counter]); | ||||
183 | 0 | my $authid=$listresult[$counter]; | ||||
184 | 0 | my $summary=BuildSummary($authrecord,$authid,$authtypecode); | ||||
185 | 0 | my $query_auth_tag = "SELECT auth_tag_to_report FROM auth_types WHERE authtypecode=?"; | ||||
186 | 0 | my $sth = $dbh->prepare($query_auth_tag); | ||||
187 | 0 | $sth->execute($authtypecode); | ||||
188 | 0 | my $auth_tag_to_report = $sth->fetchrow; | ||||
189 | 0 | my %newline; | ||||
190 | 0 | $newline{used}=CountUsage($authid); | ||||
191 | 0 | $newline{summary} = $summary; | ||||
192 | 0 | $newline{authid} = $authid; | ||||
193 | 0 | $newline{even} = $counter % 2; | ||||
194 | 0 | push @finalresult, \%newline; | ||||
195 | 0 | } | ||||
196 | 0 | return (\@finalresult, $numbers); | ||||
197 | } else { | |||||
198 | 0 | return; | ||||
199 | } | |||||
200 | } else { | |||||
201 | 0 | my $query; | ||||
202 | 0 | my $attr; | ||||
203 | # the marclist may contain "mainentry". In this case, search the tag_to_report, that depends on | |||||
204 | # the authtypecode. Then, search on $a of this tag_to_report | |||||
205 | # also store main entry MARC tag, to extract it at end of search | |||||
206 | 0 | my $mainentrytag; | ||||
207 | ##first set the authtype search and may be multiple authorities | |||||
208 | 0 | my $n=0; | ||||
209 | 0 | my @authtypecode; | ||||
210 | 0 | my @auths=split / /,$authtypecode ; | ||||
211 | 0 | foreach my $auth (@auths){ | ||||
212 | 0 | $query .=" \@attr 1=authtype \@attr 5=100 ".$auth; ##No truncation on authtype | ||||
213 | 0 | push @authtypecode ,$auth; | ||||
214 | 0 | $n++; | ||||
215 | } | |||||
216 | 0 | if ($n>1){ | ||||
217 | 0 0 0 | while ($n>1){$query= "\@or ".$query;$n--;} | ||||
218 | } | |||||
219 | ||||||
220 | 0 | my $dosearch; | ||||
221 | 0 | my $and=" \@and " ; | ||||
222 | 0 | my $q2; | ||||
223 | 0 | my $attr_cnt = 0; | ||||
224 | 0 | for(my $i = 0 ; $i <= $#{$value} ; $i++) | ||||
225 | { | |||||
226 | 0 | if (@$value[$i]){ | ||||
227 | 0 | if ( @$tags[$i] eq "mainmainentry" ) { | ||||
228 | 0 | $attr = " \@attr 1=Heading-Main "; | ||||
229 | } | |||||
230 | elsif ( @$tags[$i] eq "mainentry" ) { | |||||
231 | 0 | $attr = " \@attr 1=Heading "; | ||||
232 | } | |||||
233 | elsif ( @$tags[$i] eq "any" ) { | |||||
234 | 0 | $attr = " \@attr 1=Any "; | ||||
235 | } | |||||
236 | elsif ( @$tags[$i] eq "match" ) { | |||||
237 | 0 | $attr = " \@attr 1=Match "; | ||||
238 | } | |||||
239 | elsif ( @$tags[$i] eq "match-heading" ) { | |||||
240 | 0 | $attr = " \@attr 1=Match-heading "; | ||||
241 | } | |||||
242 | elsif ( @$tags[$i] eq "see-from" ) { | |||||
243 | 0 | $attr = " \@attr 1=Match-heading-see-from "; | ||||
244 | } | |||||
245 | elsif ( @$tags[$i] eq "thesaurus" ) { | |||||
246 | 0 | $attr = " \@attr 1=Subject-heading-thesaurus "; | ||||
247 | } | |||||
248 | 0 | if ( @$operator[$i] eq 'is' ) { | ||||
249 | 0 | $attr .= " \@attr 4=1 \@attr 5=100 " | ||||
250 | ; ##Phrase, No truncation,all of subfield field must match | |||||
251 | } | |||||
252 | elsif ( @$operator[$i] eq "=" ) { | |||||
253 | 0 | $attr .= " \@attr 4=107 "; #Number Exact match | ||||
254 | } | |||||
255 | elsif ( @$operator[$i] eq "start" ) { | |||||
256 | 0 | $attr .= " \@attr 3=2 \@attr 4=1 \@attr 5=1 " | ||||
257 | ; #Firstinfield Phrase, Right truncated | |||||
258 | } | |||||
259 | elsif ( @$operator[$i] eq "exact" ) { | |||||
260 | 0 | $attr .= " \@attr 4=1 \@attr 5=100 \@attr 6=3 " | ||||
261 | ; ##Phrase, No truncation,all of subfield field must match | |||||
262 | } | |||||
263 | else { | |||||
264 | 0 | $attr .= " \@attr 5=1 \@attr 4=6 " | ||||
265 | ; ## Word list, right truncated, anywhere | |||||
266 | } | |||||
267 | 0 | @$value[$i] =~ s/"/\\"/g; # Escape the double-quotes in the search value | ||||
268 | 0 | $attr =$attr."\"".@$value[$i]."\""; | ||||
269 | 0 | $q2 .=$attr; | ||||
270 | 0 | $dosearch=1; | ||||
271 | 0 | ++$attr_cnt; | ||||
272 | }#if value | |||||
273 | 0 | } | ||||
274 | ##Add how many queries generated | |||||
275 | 0 | if (defined $query && $query=~/\S+/){ | ||||
276 | 0 | $query= $and x $attr_cnt . $query . (defined $q2 ? $q2 : ''); | ||||
277 | } else { | |||||
278 | 0 | $query= $q2; | ||||
279 | } | |||||
280 | ## Adding order | |||||
281 | #$query=' @or @attr 7=2 @attr 1=Heading 0 @or @attr 7=1 @attr 1=Heading 1'.$query if ($sortby eq "HeadingDsc"); | |||||
282 | 0 | my $orderstring= ($sortby eq "HeadingAsc"? | ||||
283 | '@attr 7=1 @attr 1=Heading 0' | |||||
284 | : | |||||
285 | $sortby eq "HeadingDsc"? | |||||
286 | '@attr 7=2 @attr 1=Heading 0' | |||||
287 | :'' | |||||
288 | ); | |||||
289 | 0 | $query=($query?$query:"\@attr 1=_ALLRECORDS \@attr 2=103 ''"); | ||||
290 | 0 | $query="\@or $orderstring $query" if $orderstring; | ||||
291 | ||||||
292 | 0 | $offset=0 unless $offset; | ||||
293 | 0 | my $counter = $offset; | ||||
294 | 0 | $length=10 unless $length; | ||||
295 | 0 | my @oAuth; | ||||
296 | 0 | my $i; | ||||
297 | 0 | $oAuth[0]=C4::Context->Zconn("authorityserver" , 1); | ||||
298 | 0 | my $Anewq= new ZOOM::Query::PQF($query,$oAuth[0]); | ||||
299 | 0 | my $oAResult; | ||||
300 | 0 | $oAResult= $oAuth[0]->search($Anewq) ; | ||||
301 | 0 | while (($i = ZOOM::event(\@oAuth)) != 0) { | ||||
302 | 0 | my $ev = $oAuth[$i-1]->last_event(); | ||||
303 | 0 | last if $ev == ZOOM::Event::ZEND; | ||||
304 | } | |||||
305 | 0 | my($error, $errmsg, $addinfo, $diagset) = $oAuth[0]->error_x(); | ||||
306 | 0 | if ($error) { | ||||
307 | 0 | warn "oAuth error: $errmsg ($error) $addinfo $diagset\n"; | ||||
308 | 0 | goto NOLUCK; | ||||
309 | } | |||||
310 | ||||||
311 | 0 | my $nbresults; | ||||
312 | 0 | $nbresults=$oAResult->size(); | ||||
313 | 0 | my $nremains=$nbresults; | ||||
314 | 0 | my @result = (); | ||||
315 | 0 | my @finalresult = (); | ||||
316 | ||||||
317 | 0 | if ($nbresults>0){ | ||||
318 | ||||||
319 | ##Find authid and linkid fields | |||||
320 | ##we may be searching multiple authoritytypes. | |||||
321 | ## FIXME this assumes that all authid and linkid fields are the same for all authority types | |||||
322 | # my ($authidfield,$authidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.authid",$authtypecode[0]); | |||||
323 | # my ($linkidfield,$linkidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.linkid",$authtypecode[0]); | |||||
324 | 0 | while (($counter < $nbresults) && ($counter < ($offset + $length))) { | ||||
325 | ||||||
326 | ##Here we have to extract MARC record and $authid from ZEBRA AUTHORITIES | |||||
327 | 0 | my $rec=$oAResult->record($counter); | ||||
328 | 0 | my $marcdata=$rec->raw(); | ||||
329 | 0 | my $authrecord; | ||||
330 | 0 | my $separator=C4::Context->preference('authoritysep'); | ||||
331 | 0 | $authrecord = MARC::File::USMARC::decode($marcdata); | ||||
332 | 0 | my $authid=$authrecord->field('001')->data(); | ||||
333 | 0 | my %newline; | ||||
334 | 0 | $newline{authid} = $authid; | ||||
335 | 0 | if ( !$skipmetadata ) { | ||||
336 | 0 | my $summary = | ||||
337 | BuildSummary( $authrecord, $authid, $authtypecode ); | |||||
338 | 0 | my $query_auth_tag = | ||||
339 | "SELECT auth_tag_to_report FROM auth_types WHERE authtypecode=?"; | |||||
340 | 0 | my $sth = $dbh->prepare($query_auth_tag); | ||||
341 | 0 | $sth->execute($authtypecode); | ||||
342 | 0 | my $auth_tag_to_report = $sth->fetchrow; | ||||
343 | 0 | my $reported_tag; | ||||
344 | 0 | my $mainentry = $authrecord->field($auth_tag_to_report); | ||||
345 | 0 | if ($mainentry) { | ||||
346 | ||||||
347 | 0 | foreach ( $mainentry->subfields() ) { | ||||
348 | 0 | $reported_tag .= '$' . $_->[0] . $_->[1]; | ||||
349 | } | |||||
350 | } | |||||
351 | 0 | $newline{summary} = $summary; | ||||
352 | 0 | $newline{even} = $counter % 2; | ||||
353 | 0 | $newline{reported_tag} = $reported_tag; | ||||
354 | } | |||||
355 | 0 | $counter++; | ||||
356 | 0 | push @finalresult, \%newline; | ||||
357 | }## while counter | |||||
358 | ### | |||||
359 | 0 | if (! $skipmetadata) { | ||||
360 | for (my $z=0; $z<@finalresult; $z++){ | |||||
361 | 0 | my $count=CountUsage($finalresult[$z]{authid}); | ||||
362 | 0 | $finalresult[$z]{used}=$count; | ||||
363 | 0 | }# all $z's | ||||
364 | } | |||||
365 | ||||||
366 | }## if nbresult | |||||
367 | NOLUCK: | |||||
368 | 0 | $oAResult->destroy(); | ||||
369 | # $oAuth[0]->destroy(); | |||||
370 | ||||||
371 | 0 | return (\@finalresult, $nbresults); | ||||
372 | } | |||||
373 | } | |||||
374 | ||||||
375 - 381 | =head2 CountUsage $count= &CountUsage($authid) counts Usage of Authid in bibliorecords. =cut | |||||
382 | ||||||
383 | sub CountUsage { | |||||
384 | 0 | my ($authid) = @_; | ||||
385 | 0 | if (C4::Context->preference('NoZebra')) { | ||||
386 | # Read the index Koha-Auth-Number for this authid and count the lines | |||||
387 | 0 | my $result = C4::Search::NZanalyse("an=$authid"); | ||||
388 | 0 | my @tab = split /;/,$result; | ||||
389 | 0 | return scalar @tab; | ||||
390 | } else { | |||||
391 | ### ZOOM search here | |||||
392 | 0 | my $query; | ||||
393 | 0 | $query= "an=".$authid; | ||||
394 | 0 | my ($err,$res,$result) = C4::Search::SimpleSearch($query,0,10); | ||||
395 | 0 | if ($err) { | ||||
396 | 0 | warn "Error: $err from search $query"; | ||||
397 | 0 | $result = 0; | ||||
398 | } | |||||
399 | ||||||
400 | 0 | return $result; | ||||
401 | } | |||||
402 | } | |||||
403 | ||||||
404 - 410 | =head2 CountUsageChildren $count= &CountUsageChildren($authid) counts Usage of narrower terms of Authid in bibliorecords. =cut | |||||
411 | ||||||
412 | sub CountUsageChildren { | |||||
413 | 0 | my ($authid) = @_; | ||||
414 | } | |||||
415 | ||||||
416 - 422 | =head2 GetAuthTypeCode $authtypecode= &GetAuthTypeCode($authid) returns authtypecode of an authid =cut | |||||
423 | ||||||
424 | sub GetAuthTypeCode { | |||||
425 | #AUTHfind_authtypecode | |||||
426 | 0 | my ($authid) = @_; | ||||
427 | 0 | my $dbh=C4::Context->dbh; | ||||
428 | 0 | my $sth = $dbh->prepare("select authtypecode from auth_header where authid=?"); | ||||
429 | 0 | $sth->execute($authid); | ||||
430 | 0 | my $authtypecode = $sth->fetchrow; | ||||
431 | 0 | return $authtypecode; | ||||
432 | } | |||||
433 | ||||||
434 - 440 | =head2 GuessAuthTypeCode my $authtypecode = GuessAuthTypeCode($record); Get the record and tries to guess the adequate authtypecode from its content. =cut | |||||
441 | ||||||
442 | sub GuessAuthTypeCode { | |||||
443 | 0 | my ($record) = @_; | ||||
444 | 0 | return unless defined $record; | ||||
445 | 0 | my $heading_fields = { | ||||
446 | "MARC21"=>{ | |||||
447 | '100'=>{authtypecode=>'PERSO_NAME'}, | |||||
448 | '110'=>{authtypecode=>'CORPO_NAME'}, | |||||
449 | '111'=>{authtypecode=>'MEETI_NAME'}, | |||||
450 | '130'=>{authtypecode=>'UNIF_TITLE'}, | |||||
451 | '148'=>{authtypecode=>'CHRON_TERM'}, | |||||
452 | '150'=>{authtypecode=>'TOPIC_TERM'}, | |||||
453 | '151'=>{authtypecode=>'GEOGR_NAME'}, | |||||
454 | '155'=>{authtypecode=>'GENRE/FORM'}, | |||||
455 | '180'=>{authtypecode=>'GEN_SUBDIV'}, | |||||
456 | '181'=>{authtypecode=>'GEO_SUBDIV'}, | |||||
457 | '182'=>{authtypecode=>'CHRON_SUBD'}, | |||||
458 | '185'=>{authtypecode=>'FORM_SUBD'}, | |||||
459 | }, | |||||
460 | #200 Personal name 700, 701, 702 4-- with embedded 700, 701, 702 600 | |||||
461 | # 604 with embedded 700, 701, 702 | |||||
462 | #210 Corporate or meeting name 710, 711, 712 4-- with embedded 710, 711, 712 601 604 with embedded 710, 711, 712 | |||||
463 | #215 Territorial or geographic name 710, 711, 712 4-- with embedded 710, 711, 712 601, 607 604 with embedded 710, 711, 712 | |||||
464 | #216 Trademark 716 [Reserved for future use] | |||||
465 | #220 Family name 720, 721, 722 4-- with embedded 720, 721, 722 602 604 with embedded 720, 721, 722 | |||||
466 | #230 Title 500 4-- with embedded 500 605 | |||||
467 | #240 Name and title (embedded 200, 210, 215, or 220 and 230) 4-- with embedded 7-- and 500 7-- 604 with embedded 7-- and 500 500 | |||||
468 | #245 Name and collective title (embedded 200, 210, 215, or 220 and 235) 4-- with embedded 7-- and 501 604 with embedded 7-- and 501 7-- 501 | |||||
469 | #250 Topical subject 606 | |||||
470 | #260 Place access 620 | |||||
471 | #280 Form, genre or physical characteristics 608 | |||||
472 | # | |||||
473 | # | |||||
474 | # Could also be represented with : | |||||
475 | #leader position 9 | |||||
476 | #a = personal name entry | |||||
477 | #b = corporate name entry | |||||
478 | #c = territorial or geographical name | |||||
479 | #d = trademark | |||||
480 | #e = family name | |||||
481 | #f = uniform title | |||||
482 | #g = collective uniform title | |||||
483 | #h = name/title | |||||
484 | #i = name/collective uniform title | |||||
485 | #j = topical subject | |||||
486 | #k = place access | |||||
487 | #l = form, genre or physical characteristics | |||||
488 | "UNIMARC"=>{ | |||||
489 | '200'=>{authtypecode=>'NP'}, | |||||
490 | '210'=>{authtypecode=>'CO'}, | |||||
491 | '215'=>{authtypecode=>'SNG'}, | |||||
492 | '216'=>{authtypecode=>'TM'}, | |||||
493 | '220'=>{authtypecode=>'FAM'}, | |||||
494 | '230'=>{authtypecode=>'TU'}, | |||||
495 | '235'=>{authtypecode=>'CO_UNI_TI'}, | |||||
496 | '240'=>{authtypecode=>'SAUTTIT'}, | |||||
497 | '245'=>{authtypecode=>'NAME_COL'}, | |||||
498 | '250'=>{authtypecode=>'SNC'}, | |||||
499 | '260'=>{authtypecode=>'PA'}, | |||||
500 | '280'=>{authtypecode=>'GENRE/FORM'}, | |||||
501 | } | |||||
502 | }; | |||||
503 | 0 0 | foreach my $field (keys %{$heading_fields->{uc(C4::Context->preference('marcflavour'))} }) { | ||||
504 | 0 | return $heading_fields->{uc(C4::Context->preference('marcflavour'))}->{$field}->{'authtypecode'} if (defined $record->field($field)); | ||||
505 | } | |||||
506 | 0 | return; | ||||
507 | } | |||||
508 | ||||||
509 - 515 | =head2 GuessAuthId my $authtid = GuessAuthId($record); Get the record and tries to guess the adequate authtypecode from its content. =cut | |||||
516 | ||||||
517 | sub GuessAuthId { | |||||
518 | 0 | my ($record) = @_; | ||||
519 | 0 | return unless ($record && $record->field('001')); | ||||
520 | # my $authtypecode=GuessAuthTypeCode($record); | |||||
521 | # my ($tag,$subfield)=GetAuthMARCFromKohaField("auth_header.authid",$authtypecode); | |||||
522 | # if ($tag > 010) {return $record->subfield($tag,$subfield)} | |||||
523 | # else {return $record->field($tag)->data} | |||||
524 | 0 | return $record->field('001')->data; | ||||
525 | } | |||||
526 | ||||||
527 - 552 | =head2 GetTagsLabels $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 =cut | |||||
553 | ||||||
554 | sub GetTagsLabels { | |||||
555 | 0 | my ($forlibrarian,$authtypecode)= @_; | ||||
556 | 0 | my $dbh=C4::Context->dbh; | ||||
557 | 0 | $authtypecode="" unless $authtypecode; | ||||
558 | 0 | my $sth; | ||||
559 | 0 | my $libfield = ($forlibrarian == 1)? 'liblibrarian' : 'libopac'; | ||||
560 | ||||||
561 | ||||||
562 | # check that authority exists | |||||
563 | 0 | $sth=$dbh->prepare("SELECT count(*) FROM auth_tag_structure WHERE authtypecode=?"); | ||||
564 | 0 | $sth->execute($authtypecode); | ||||
565 | 0 | my ($total) = $sth->fetchrow; | ||||
566 | 0 | $authtypecode="" unless ($total >0); | ||||
567 | 0 | $sth= $dbh->prepare( | ||||
568 | "SELECT auth_tag_structure.tagfield,auth_tag_structure.liblibrarian,auth_tag_structure.libopac,auth_tag_structure.mandatory,auth_tag_structure.repeatable | |||||
569 | FROM auth_tag_structure | |||||
570 | WHERE authtypecode=? | |||||
571 | ORDER BY tagfield" | |||||
572 | ); | |||||
573 | ||||||
574 | 0 | $sth->execute($authtypecode); | ||||
575 | 0 | my ( $liblibrarian, $libopac, $tag, $res, $tab, $mandatory, $repeatable ); | ||||
576 | ||||||
577 | 0 | while ( ( $tag, $liblibrarian, $libopac, $mandatory, $repeatable ) = $sth->fetchrow ) { | ||||
578 | 0 | $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac; | ||||
579 | 0 | $res->{$tag}->{tab} = " "; # XXX | ||||
580 | 0 | $res->{$tag}->{mandatory} = $mandatory; | ||||
581 | 0 | $res->{$tag}->{repeatable} = $repeatable; | ||||
582 | } | |||||
583 | 0 | $sth= $dbh->prepare( | ||||
584 | "SELECT tagfield,tagsubfield,liblibrarian,libopac,tab, mandatory, repeatable,authorised_value,frameworkcode as authtypecode,value_builder,kohafield,seealso,hidden,isurl | |||||
585 | FROM auth_subfield_structure | |||||
586 | WHERE authtypecode=? | |||||
587 | ORDER BY tagfield,tagsubfield" | |||||
588 | ); | |||||
589 | 0 | $sth->execute($authtypecode); | ||||
590 | ||||||
591 | 0 | my $subfield; | ||||
592 | 0 | my $authorised_value; | ||||
593 | 0 | my $value_builder; | ||||
594 | 0 | my $kohafield; | ||||
595 | 0 | my $seealso; | ||||
596 | 0 | my $hidden; | ||||
597 | 0 | my $isurl; | ||||
598 | 0 | my $link; | ||||
599 | ||||||
600 | 0 | while ( | ||||
601 | ( $tag, $subfield, $liblibrarian, , $libopac, $tab, | |||||
602 | $mandatory, $repeatable, $authorised_value, $authtypecode, | |||||
603 | $value_builder, $kohafield, $seealso, $hidden, | |||||
604 | $isurl, $link ) | |||||
605 | = $sth->fetchrow | |||||
606 | ) | |||||
607 | { | |||||
608 | 0 | $res->{$tag}->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac; | ||||
609 | 0 | $res->{$tag}->{$subfield}->{tab} = $tab; | ||||
610 | 0 | $res->{$tag}->{$subfield}->{mandatory} = $mandatory; | ||||
611 | 0 | $res->{$tag}->{$subfield}->{repeatable} = $repeatable; | ||||
612 | 0 | $res->{$tag}->{$subfield}->{authorised_value} = $authorised_value; | ||||
613 | 0 | $res->{$tag}->{$subfield}->{authtypecode} = $authtypecode; | ||||
614 | 0 | $res->{$tag}->{$subfield}->{value_builder} = $value_builder; | ||||
615 | 0 | $res->{$tag}->{$subfield}->{kohafield} = $kohafield; | ||||
616 | 0 | $res->{$tag}->{$subfield}->{seealso} = $seealso; | ||||
617 | 0 | $res->{$tag}->{$subfield}->{hidden} = $hidden; | ||||
618 | 0 | $res->{$tag}->{$subfield}->{isurl} = $isurl; | ||||
619 | 0 | $res->{$tag}->{$subfield}->{link} = $link; | ||||
620 | } | |||||
621 | 0 | return $res; | ||||
622 | } | |||||
623 | ||||||
624 - 631 | =head2 AddAuthority $authid= &AddAuthority($record, $authid,$authtypecode) Either Create Or Modify existing authority. returns authid of the newly created authority =cut | |||||
632 | ||||||
633 | sub AddAuthority { | |||||
634 | # pass the MARC::Record to this function, and it will create the records in the authority table | |||||
635 | 0 | my ($record,$authid,$authtypecode) = @_; | ||||
636 | 0 | my $dbh=C4::Context->dbh; | ||||
637 | 0 | my $leader=' nz a22 o 4500';#Leader for incomplete MARC21 record | ||||
638 | ||||||
639 | # if authid empty => true add, find a new authid number | |||||
640 | 0 | my $format; | ||||
641 | 0 | if (uc(C4::Context->preference('marcflavour')) eq 'UNIMARC') { | ||||
642 | 0 | $format= 'UNIMARCAUTH'; | ||||
643 | } | |||||
644 | else { | |||||
645 | 0 | $format= 'MARC21'; | ||||
646 | } | |||||
647 | ||||||
648 | #update date/time to 005 for marc and unimarc | |||||
649 | 0 | my $time=POSIX::strftime("%Y%m%d%H%M%S",localtime); | ||||
650 | 0 | my $f5=$record->field('005'); | ||||
651 | 0 | if (!$f5) { | ||||
652 | 0 | $record->insert_fields_ordered( MARC::Field->new('005',$time.".0") ); | ||||
653 | } | |||||
654 | else { | |||||
655 | 0 | $f5->update($time.".0"); | ||||
656 | } | |||||
657 | ||||||
658 | 0 | SetUTF8Flag($record); | ||||
659 | 0 | if ($format eq "MARC21") { | ||||
660 | 0 | if (!$record->leader) { | ||||
661 | 0 | $record->leader($leader); | ||||
662 | } | |||||
663 | 0 | if (!$record->field('003')) { | ||||
664 | 0 | $record->insert_fields_ordered( | ||||
665 | MARC::Field->new('003',C4::Context->preference('MARCOrgCode')) | |||||
666 | ); | |||||
667 | } | |||||
668 | 0 | my $date=POSIX::strftime("%y%m%d",localtime); | ||||
669 | 0 | if (!$record->field('008')) { | ||||
670 | # Get a valid default value for field 008 | |||||
671 | 0 | my $default_008 = C4::Context->preference('MARCAuthorityControlField008'); | ||||
672 | 0 | if(!$default_008 or length($default_008)<34) { | ||||
673 | 0 | $default_008 = '|| aca||aabn | a|a d'; | ||||
674 | } | |||||
675 | else { | |||||
676 | 0 | $default_008 = substr($default_008,0,34); | ||||
677 | } | |||||
678 | ||||||
679 | 0 | $record->insert_fields_ordered( MARC::Field->new('008',$date.$default_008) ); | ||||
680 | } | |||||
681 | 0 | if (!$record->field('040')) { | ||||
682 | 0 | $record->insert_fields_ordered( | ||||
683 | MARC::Field->new('040','','', | |||||
684 | 'a' => C4::Context->preference('MARCOrgCode'), | |||||
685 | 'c' => C4::Context->preference('MARCOrgCode') | |||||
686 | ) | |||||
687 | ); | |||||
688 | } | |||||
689 | } | |||||
690 | ||||||
691 | 0 | if ($format eq "UNIMARCAUTH") { | ||||
692 | 0 | $record->leader(" nx j22 ") unless ($record->leader()); | ||||
693 | 0 | my $date=POSIX::strftime("%Y%m%d",localtime); | ||||
694 | 0 | if (my $string=$record->subfield('100',"a")){ | ||||
695 | 0 | $string=~s/fre50/frey50/; | ||||
696 | 0 | $record->field('100')->update('a'=>$string); | ||||
697 | } | |||||
698 | elsif ($record->field('100')){ | |||||
699 | 0 | $record->field('100')->update('a'=>$date."afrey50 ba0"); | ||||
700 | } else { | |||||
701 | 0 | $record->append_fields( | ||||
702 | MARC::Field->new('100',' ',' ' | |||||
703 | ,'a'=>$date."afrey50 ba0") | |||||
704 | ); | |||||
705 | } | |||||
706 | } | |||||
707 | 0 | my ($auth_type_tag, $auth_type_subfield) = get_auth_type_location($authtypecode); | ||||
708 | 0 | if (!$authid and $format eq "MARC21") { | ||||
709 | # only need to do this fix when modifying an existing authority | |||||
710 | 0 | C4::AuthoritiesMarc::MARC21::fix_marc21_auth_type_location($record, $auth_type_tag, $auth_type_subfield); | ||||
711 | } | |||||
712 | 0 | if (my $field=$record->field($auth_type_tag)){ | ||||
713 | 0 | $field->update($auth_type_subfield=>$authtypecode); | ||||
714 | } | |||||
715 | else { | |||||
716 | 0 | $record->add_fields($auth_type_tag,'','', $auth_type_subfield=>$authtypecode); | ||||
717 | } | |||||
718 | ||||||
719 | 0 | my $auth_exists=0; | ||||
720 | 0 | my $oldRecord; | ||||
721 | 0 | if (!$authid) { | ||||
722 | 0 | my $sth=$dbh->prepare("select max(authid) from auth_header"); | ||||
723 | 0 | $sth->execute; | ||||
724 | 0 | ($authid)=$sth->fetchrow; | ||||
725 | 0 | $authid=$authid+1; | ||||
726 | ##Insert the recordID in MARC record | |||||
727 | 0 | unless ($record->field('001') && $record->field('001')->data() eq $authid){ | ||||
728 | 0 | $record->delete_field($record->field('001')); | ||||
729 | 0 | $record->insert_fields_ordered(MARC::Field->new('001',$authid)); | ||||
730 | } | |||||
731 | } else { | |||||
732 | 0 | $auth_exists=$dbh->do(qq(select authid from auth_header where authid=?),undef,$authid); | ||||
733 | # warn "auth_exists = $auth_exists"; | |||||
734 | } | |||||
735 | 0 | if ($auth_exists>0){ | ||||
736 | 0 | $oldRecord=GetAuthority($authid); | ||||
737 | 0 | $record->add_fields('001',$authid) unless ($record->field('001')); | ||||
738 | # warn "\n\n\n enregistrement".$record->as_formatted; | |||||
739 | 0 | my $sth=$dbh->prepare("update auth_header set authtypecode=?,marc=?,marcxml=? where authid=?"); | ||||
740 | 0 | $sth->execute($authtypecode,$record->as_usmarc,$record->as_xml_record($format),$authid) or die $sth->errstr; | ||||
741 | 0 | $sth->finish; | ||||
742 | } | |||||
743 | else { | |||||
744 | 0 | my $sth=$dbh->prepare("insert into auth_header (authid,datecreated,authtypecode,marc,marcxml) values (?,now(),?,?,?)"); | ||||
745 | 0 | $sth->execute($authid,$authtypecode,$record->as_usmarc,$record->as_xml_record($format)); | ||||
746 | 0 | $sth->finish; | ||||
747 | 0 | logaction( "AUTHORITIES", "ADD", $authid, "authority" ) if C4::Context->preference("AuthoritiesLog"); | ||||
748 | } | |||||
749 | 0 | ModZebra($authid,'specialUpdate',"authorityserver",$oldRecord,$record); | ||||
750 | 0 | return ($authid); | ||||
751 | } | |||||
752 | ||||||
753 | ||||||
754 - 760 | =head2 DelAuthority $authid= &DelAuthority($authid) Deletes $authid =cut | |||||
761 | ||||||
762 | sub DelAuthority { | |||||
763 | 0 | my ($authid) = @_; | ||||
764 | 0 | my $dbh=C4::Context->dbh; | ||||
765 | ||||||
766 | 0 | logaction( "AUTHORITIES", "DELETE", $authid, "authority" ) if C4::Context->preference("AuthoritiesLog"); | ||||
767 | 0 | ModZebra($authid,"recordDelete","authorityserver",GetAuthority($authid),undef); | ||||
768 | 0 | my $sth = $dbh->prepare("DELETE FROM auth_header WHERE authid=?"); | ||||
769 | 0 | $sth->execute($authid); | ||||
770 | } | |||||
771 | ||||||
772 - 778 | =head2 ModAuthority $authid= &ModAuthority($authid,$record,$authtypecode) Modifies authority record, optionally updates attached biblios. =cut | |||||
779 | ||||||
780 | sub ModAuthority { | |||||
781 | 0 | my ($authid,$record,$authtypecode)=@_; # deprecated $merge parameter removed | ||||
782 | ||||||
783 | 0 | my $dbh=C4::Context->dbh; | ||||
784 | #Now rewrite the $record to table with an add | |||||
785 | 0 | my $oldrecord=GetAuthority($authid); | ||||
786 | 0 | $authid=AddAuthority($record,$authid,$authtypecode); | ||||
787 | ||||||
788 | # If a library thinks that updating all biblios is a long process and wishes | |||||
789 | # to leave that to a cron job, use misc/migration_tools/merge_authority.pl. | |||||
790 | # In that case set system preference "dontmerge" to 1. Otherwise biblios will | |||||
791 | # be updated. | |||||
792 | 0 | unless(C4::Context->preference('dontmerge') eq '1'){ | ||||
793 | 0 | &merge($authid,$oldrecord,$authid,$record); | ||||
794 | } else { | |||||
795 | # save a record in need_merge_authorities table | |||||
796 | 0 | my $sqlinsert="INSERT INTO need_merge_authorities (authid, done) ". | ||||
797 | "VALUES (?,?)"; | |||||
798 | 0 | $dbh->do($sqlinsert,undef,($authid,0)); | ||||
799 | } | |||||
800 | 0 | logaction( "AUTHORITIES", "MODIFY", $authid, "BEFORE=>" . $oldrecord->as_formatted ) if C4::Context->preference("AuthoritiesLog"); | ||||
801 | 0 | return $authid; | ||||
802 | } | |||||
803 | ||||||
804 - 810 | =head2 GetAuthorityXML $marcxml= &GetAuthorityXML( $authid) returns xml form of record $authid =cut | |||||
811 | ||||||
812 | sub GetAuthorityXML { | |||||
813 | # Returns MARC::XML of the authority passed in parameter. | |||||
814 | 0 | my ( $authid ) = @_; | ||||
815 | 0 | if (uc(C4::Context->preference('marcflavour')) eq 'UNIMARC') { | ||||
816 | 0 | my $dbh=C4::Context->dbh; | ||||
817 | 0 | my $sth = $dbh->prepare("select marcxml from auth_header where authid=? " ); | ||||
818 | 0 | $sth->execute($authid); | ||||
819 | 0 | my ($marcxml)=$sth->fetchrow; | ||||
820 | 0 | return $marcxml; | ||||
821 | } | |||||
822 | else { | |||||
823 | # for MARC21, call GetAuthority instead of | |||||
824 | # getting the XML directly since we may | |||||
825 | # need to fix up the location of the authority | |||||
826 | # code -- note that this is reasonably safe | |||||
827 | # because GetAuthorityXML is used only by the | |||||
828 | # indexing processes like zebraqueue_start.pl | |||||
829 | 0 | my $record = GetAuthority($authid); | ||||
830 | 0 | return $record->as_xml_record('MARC21'); | ||||
831 | } | |||||
832 | } | |||||
833 | ||||||
834 - 840 | =head2 GetAuthority $record= &GetAuthority( $authid) Returns MARC::Record of the authority passed in parameter. =cut | |||||
841 | ||||||
842 | sub GetAuthority { | |||||
843 | 0 | my ($authid)=@_; | ||||
844 | 0 | my $dbh=C4::Context->dbh; | ||||
845 | 0 | my $sth=$dbh->prepare("select authtypecode, marcxml from auth_header where authid=?"); | ||||
846 | 0 | $sth->execute($authid); | ||||
847 | 0 | my ($authtypecode, $marcxml) = $sth->fetchrow; | ||||
848 | 0 0 | my $record=eval {MARC::Record->new_from_xml(StripNonXmlChars($marcxml),'UTF-8', | ||||
849 | (C4::Context->preference("marcflavour") eq "UNIMARC"?"UNIMARCAUTH":C4::Context->preference("marcflavour")))}; | |||||
850 | 0 | return undef if ($@); | ||||
851 | 0 | $record->encoding('UTF-8'); | ||||
852 | 0 | if (C4::Context->preference("marcflavour") eq "MARC21") { | ||||
853 | 0 | my ($auth_type_tag, $auth_type_subfield) = get_auth_type_location($authtypecode); | ||||
854 | 0 | C4::AuthoritiesMarc::MARC21::fix_marc21_auth_type_location($record, $auth_type_tag, $auth_type_subfield); | ||||
855 | } | |||||
856 | 0 | return ($record); | ||||
857 | } | |||||
858 | ||||||
859 - 867 | =head2 GetAuthType $result = &GetAuthType($authtypecode) 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 | |||||
868 | ||||||
869 | sub GetAuthType { | |||||
870 | 0 | my ($authtypecode) = @_; | ||||
871 | 0 | my $dbh=C4::Context->dbh; | ||||
872 | 0 | my $sth; | ||||
873 | 0 | if (defined $authtypecode){ # NOTE - in MARC21 framework, '' is a valid authority | ||||
874 | # type (FIXME but why?) | |||||
875 | 0 | $sth=$dbh->prepare("select * from auth_types where authtypecode=?"); | ||||
876 | 0 | $sth->execute($authtypecode); | ||||
877 | 0 | if (my $res = $sth->fetchrow_hashref) { | ||||
878 | 0 | return $res; | ||||
879 | } | |||||
880 | } | |||||
881 | 0 | return; | ||||
882 | } | |||||
883 | ||||||
884 | ||||||
885 - 893 | =head2 FindDuplicateAuthority $record= &FindDuplicateAuthority( $record, $authtypecode) return $authid,Summary if duplicate is found. Comments : an improvement would be to return All the records that match. =cut | |||||
894 | ||||||
895 | sub FindDuplicateAuthority { | |||||
896 | ||||||
897 | 0 | my ($record,$authtypecode)=@_; | ||||
898 | # warn "IN for ".$record->as_formatted; | |||||
899 | 0 | my $dbh = C4::Context->dbh; | ||||
900 | # warn "".$record->as_formatted; | |||||
901 | 0 | my $sth = $dbh->prepare("select auth_tag_to_report from auth_types where authtypecode=?"); | ||||
902 | 0 | $sth->execute($authtypecode); | ||||
903 | 0 | my ($auth_tag_to_report) = $sth->fetchrow; | ||||
904 | 0 | $sth->finish; | ||||
905 | # warn "record :".$record->as_formatted." auth_tag_to_report :$auth_tag_to_report"; | |||||
906 | # build a request for SearchAuthorities | |||||
907 | 0 | my $query='at='.$authtypecode.' '; | ||||
908 | 0 | my $filtervalues=qr([\001-\040\!\'\"\`\#\$\%\&\*\+,\-\./:;<=>\?\@\(\)\{\[\]\}_\|\~]); | ||||
909 | 0 | if ($record->field($auth_tag_to_report)) { | ||||
910 | 0 | foreach ($record->field($auth_tag_to_report)->subfields()) { | ||||
911 | 0 0 | $_->[1]=~s/$filtervalues/ /g; $query.= " and he,wrdl=\"".$_->[1]."\"" if ($_->[0]=~/[A-z]/); | ||||
912 | } | |||||
913 | } | |||||
914 | 0 | my ($error, $results, $total_hits) = C4::Search::SimpleSearch( $query, 0, 1, [ "authorityserver" ] ); | ||||
915 | # there is at least 1 result => return the 1st one | |||||
916 | 0 0 | if (!defined $error && @{$results} ) { | ||||
917 | 0 | my $marcrecord = MARC::File::USMARC::decode($results->[0]); | ||||
918 | 0 | return $marcrecord->field('001')->data,BuildSummary($marcrecord,$marcrecord->field('001')->data,$authtypecode); | ||||
919 | } | |||||
920 | # no result, returns nothing | |||||
921 | 0 | return; | ||||
922 | } | |||||
923 | ||||||
924 - 934 | =head2 BuildSummary $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. =cut | |||||
935 | ||||||
936 | sub BuildSummary{ | |||||
937 | ## give this a Marc record to return summary | |||||
938 | 0 | my ($record,$authid,$authtypecode)=@_; | ||||
939 | 0 | my $dbh=C4::Context->dbh; | ||||
940 | 0 | my $summary; | ||||
941 | # handle $authtypecode is NULL or eq "" | |||||
942 | 0 | if ($authtypecode) { | ||||
943 | 0 | my $authref = GetAuthType($authtypecode); | ||||
944 | 0 | $summary = $authref->{summary}; | ||||
945 | } | |||||
946 | # FIXME: should use I18N.pm | |||||
947 | 0 | my %language; | ||||
948 | 0 | $language{'fre'}="Français"; | ||||
949 | 0 | $language{'eng'}="Anglais"; | ||||
950 | 0 | $language{'ger'}="Allemand"; | ||||
951 | 0 | $language{'ita'}="Italien"; | ||||
952 | 0 | $language{'spa'}="Espagnol"; | ||||
953 | 0 | my %thesaurus; | ||||
954 | 0 | $thesaurus{'1'}="Peuples"; | ||||
955 | 0 | $thesaurus{'2'}="Anthroponymes"; | ||||
956 | 0 | $thesaurus{'3'}="Oeuvres"; | ||||
957 | 0 | $thesaurus{'4'}="Chronologie"; | ||||
958 | 0 | $thesaurus{'5'}="Lieux"; | ||||
959 | 0 | $thesaurus{'6'}="Sujets"; | ||||
960 | #thesaurus a remplir | |||||
961 | 0 | my @fields = $record->fields(); | ||||
962 | 0 | my $reported_tag; | ||||
963 | # if the library has a summary defined, use it. Otherwise, build a standard one | |||||
964 | # FIXME - it appears that the summary field in the authority frameworks | |||||
965 | # can work as a display template. However, this doesn't | |||||
966 | # suit the MARC21 version, so for now the "templating" | |||||
967 | # feature will be enabled only for UNIMARC for backwards | |||||
968 | # compatibility. | |||||
969 | 0 | if ($summary and C4::Context->preference('marcflavour') eq 'UNIMARC') { | ||||
970 | 0 | my @fields = $record->fields(); | ||||
971 | # $reported_tag = '$9'.$result[$counter]; | |||||
972 | 0 | my @stringssummary; | ||||
973 | 0 | foreach my $field (@fields) { | ||||
974 | 0 | my $tag = $field->tag(); | ||||
975 | 0 | my $tagvalue = $field->as_string(); | ||||
976 | 0 | my $localsummary= $summary; | ||||
977 | 0 | $localsummary =~ s/\[(.?.?.?.?)$tag\*(.*?)\]/$1$tagvalue$2\[$1$tag$2\]/g; | ||||
978 | 0 | if ($tag<10) { | ||||
979 | 0 | if ($tag eq '001') { | ||||
980 | 0 | $reported_tag.='$3'.$field->data(); | ||||
981 | } | |||||
982 | } else { | |||||
983 | 0 | my @subf = $field->subfields; | ||||
984 | 0 | for my $i (0..$#subf) { | ||||
985 | 0 | my $subfieldcode = $subf[$i][0]; | ||||
986 | 0 | my $subfieldvalue = $subf[$i][1]; | ||||
987 | 0 | my $tagsubf = $tag.$subfieldcode; | ||||
988 | 0 | $localsummary =~ s/\[(.?.?.?.?)$tagsubf(.*?)\]/$1$subfieldvalue$2\[$1$tagsubf$2\]/g; | ||||
989 | } | |||||
990 | } | |||||
991 | 0 | push @stringssummary, $localsummary if ($localsummary ne $summary); | ||||
992 | } | |||||
993 | 0 | my $resultstring; | ||||
994 | 0 | $resultstring = join(" -- ",@stringssummary); | ||||
995 | 0 | $resultstring =~ s/\[(.*?)\]//g; | ||||
996 | 0 | $resultstring =~ s/\n/<br>/g; | ||||
997 | 0 | $summary = $resultstring; | ||||
998 | } else { | |||||
999 | 0 | my $heading = ''; | ||||
1000 | 0 | my $altheading = ''; | ||||
1001 | 0 | my $seealso = ''; | ||||
1002 | 0 | my $broaderterms = ''; | ||||
1003 | 0 | my $narrowerterms = ''; | ||||
1004 | 0 | my $see = ''; | ||||
1005 | 0 | my $seeheading = ''; | ||||
1006 | 0 | my $notes = ''; | ||||
1007 | 0 | my @fields = $record->fields(); | ||||
1008 | 0 | if (C4::Context->preference('marcflavour') eq 'UNIMARC') { | ||||
1009 | # construct UNIMARC summary, that is quite different from MARC21 one | |||||
1010 | # accepted form | |||||
1011 | 0 | foreach my $field ($record->field('2..')) { | ||||
1012 | 0 | $heading.= $field->as_string('abcdefghijlmnopqrstuvwxyz'); | ||||
1013 | } | |||||
1014 | # rejected form(s) | |||||
1015 | 0 | foreach my $field ($record->field('3..')) { | ||||
1016 | 0 | $notes.= '<span class="note">'.$field->subfield('a')."</span>\n"; | ||||
1017 | } | |||||
1018 | 0 | foreach my $field ($record->field('4..')) { | ||||
1019 | 0 | if ($field->subfield('2')) { | ||||
1020 | 0 | my $thesaurus = "thes. : ".$thesaurus{"$field->subfield('2')"}." : "; | ||||
1021 | 0 | $see.= '<span class="UF">'.$thesaurus.$field->as_string('abcdefghijlmnopqrstuvwxyz')."</span> -- \n"; | ||||
1022 | } | |||||
1023 | } | |||||
1024 | # see : | |||||
1025 | 0 | foreach my $field ($record->field('5..')) { | ||||
1026 | ||||||
1027 | 0 | if (($field->subfield('5')) && ($field->subfield('a')) && ($field->subfield('5') eq 'g')) { | ||||
1028 | 0 | $broaderterms.= '<span class="BT"> '.$field->as_string('abcdefgjxyz')."</span> -- \n"; | ||||
1029 | } elsif (($field->subfield('5')) && ($field->as_string) && ($field->subfield('5') eq 'h')){ | |||||
1030 | 0 | $narrowerterms.= '<span class="NT">'.$field->as_string('abcdefgjxyz')."</span> -- \n"; | ||||
1031 | } elsif ($field->subfield('a')) { | |||||
1032 | 0 | $seealso.= '<span class="RT">'.$field->as_string('abcdefgxyz')."</a></span> -- \n"; | ||||
1033 | } | |||||
1034 | } | |||||
1035 | # // form | |||||
1036 | 0 | foreach my $field ($record->field('7..')) { | ||||
1037 | 0 | my $lang = substr($field->subfield('8'),3,3); | ||||
1038 | 0 | $seeheading.= '<span class="langue"> En '.$language{$lang}.' : </span><span class="OT"> '.$field->subfield('a')."</span><br />\n"; | ||||
1039 | } | |||||
1040 | 0 | $broaderterms =~s/-- \n$//; | ||||
1041 | 0 | $narrowerterms =~s/-- \n$//; | ||||
1042 | 0 | $seealso =~s/-- \n$//; | ||||
1043 | 0 | $see =~s/-- \n$//; | ||||
1044 | 0 | $summary = $heading."<br />".($notes?"$notes <br />":""); | ||||
1045 | 0 | $summary.= '<p><div class="label">TG : '.$broaderterms.'</div></p>' if ($broaderterms); | ||||
1046 | 0 | $summary.= '<p><div class="label">TS : '.$narrowerterms.'</div></p>' if ($narrowerterms); | ||||
1047 | 0 | $summary.= '<p><div class="label">TA : '.$seealso.'</div></p>' if ($seealso); | ||||
1048 | 0 | $summary.= '<p><div class="label">EP : '.$see.'</div></p>' if ($see); | ||||
1049 | 0 | $summary.= '<p><div class="label">'.$seeheading.'</div></p>' if ($seeheading); | ||||
1050 | } else { | |||||
1051 | # construct MARC21 summary | |||||
1052 | # FIXME - looping over 1XX is questionable | |||||
1053 | # since MARC21 authority should have only one 1XX | |||||
1054 | 0 | foreach my $field ($record->field('1..')) { | ||||
1055 | 0 | next if "152" eq $field->tag(); # FIXME - 152 is not a good tag to use | ||||
1056 | # in MARC21 -- purely local tags really ought to be | |||||
1057 | # 9XX | |||||
1058 | 0 | if ($record->field('100')) { | ||||
1059 | 0 | $heading.= $field->as_string('abcdefghjklmnopqrstvxyz68'); | ||||
1060 | } elsif ($record->field('110')) { | |||||
1061 | 0 | $heading.= $field->as_string('abcdefghklmnoprstvxyz68'); | ||||
1062 | } elsif ($record->field('111')) { | |||||
1063 | 0 | $heading.= $field->as_string('acdefghklnpqstvxyz68'); | ||||
1064 | } elsif ($record->field('130')) { | |||||
1065 | 0 | $heading.= $field->as_string('adfghklmnoprstvxyz68'); | ||||
1066 | } elsif ($record->field('148')) { | |||||
1067 | 0 | $heading.= $field->as_string('abvxyz68'); | ||||
1068 | } elsif ($record->field('150')) { | |||||
1069 | 0 | $heading.= $field->as_string('abvxyz68'); | ||||
1070 | #$heading.= $field->as_formatted(); | |||||
1071 | 0 | my $tag=$field->tag(); | ||||
1072 | 0 | $heading=~s /^$tag//g; | ||||
1073 | 0 | $heading =~s /\_/\$/g; | ||||
1074 | } elsif ($record->field('151')) { | |||||
1075 | 0 | $heading.= $field->as_string('avxyz68'); | ||||
1076 | } elsif ($record->field('155')) { | |||||
1077 | 0 | $heading.= $field->as_string('abvxyz68'); | ||||
1078 | } elsif ($record->field('180')) { | |||||
1079 | 0 | $heading.= $field->as_string('vxyz68'); | ||||
1080 | } elsif ($record->field('181')) { | |||||
1081 | 0 | $heading.= $field->as_string('vxyz68'); | ||||
1082 | } elsif ($record->field('182')) { | |||||
1083 | 0 | $heading.= $field->as_string('vxyz68'); | ||||
1084 | } elsif ($record->field('185')) { | |||||
1085 | 0 | $heading.= $field->as_string('vxyz68'); | ||||
1086 | } else { | |||||
1087 | 0 | $heading.= $field->as_string(); | ||||
1088 | } | |||||
1089 | } #See From | |||||
1090 | 0 | foreach my $field ($record->field('4..')) { | ||||
1091 | 0 | $seeheading.= "<br /> <i>used for/see from:</i> ".$field->as_string(); | ||||
1092 | } #See Also | |||||
1093 | 0 | foreach my $field ($record->field('5..')) { | ||||
1094 | 0 | $altheading.= "<br /> <i>see also:</i> ".$field->as_string(); | ||||
1095 | } | |||||
1096 | 0 | $summary .= ": " if $summary; | ||||
1097 | 0 | $summary.=$heading.$seeheading.$altheading; | ||||
1098 | } | |||||
1099 | } | |||||
1100 | 0 | return $summary; | ||||
1101 | } | |||||
1102 | ||||||
1103 - 1113 | =head2 BuildUnimarcHierarchies $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 =cut | |||||
1114 | ||||||
1115 | sub BuildUnimarcHierarchies{ | |||||
1116 | 0 | my $authid = shift @_; | ||||
1117 | # warn "authid : $authid"; | |||||
1118 | 0 | my $force = shift @_; | ||||
1119 | 0 | my @globalresult; | ||||
1120 | 0 | my $dbh=C4::Context->dbh; | ||||
1121 | 0 | my $hierarchies; | ||||
1122 | 0 | my $data = GetHeaderAuthority($authid); | ||||
1123 | 0 | if ($data->{'authtrees'} and not $force){ | ||||
1124 | 0 | return $data->{'authtrees'}; | ||||
1125 | # } elsif ($data->{'authtrees'}){ | |||||
1126 | # $hierarchies=$data->{'authtrees'}; | |||||
1127 | } else { | |||||
1128 | 0 | my $record = GetAuthority($authid); | ||||
1129 | 0 | my $found; | ||||
1130 | 0 | return unless $record; | ||||
1131 | 0 | foreach my $field ($record->field('5..')){ | ||||
1132 | 0 | if ($field->subfield('5') && $field->subfield('5') eq 'g'){ | ||||
1133 | 0 | my $subfauthid=_get_authid_subfield($field); | ||||
1134 | 0 | next if ($subfauthid eq $authid); | ||||
1135 | 0 | my $parentrecord = GetAuthority($subfauthid); | ||||
1136 | 0 | my $localresult=$hierarchies; | ||||
1137 | 0 | my $trees; | ||||
1138 | 0 | $trees = BuildUnimarcHierarchies($subfauthid); | ||||
1139 | 0 | my @trees; | ||||
1140 | 0 | if ($trees=~/;/){ | ||||
1141 | 0 | @trees = split(/;/,$trees); | ||||
1142 | } else { | |||||
1143 | 0 | push @trees, $trees; | ||||
1144 | } | |||||
1145 | 0 | foreach (@trees){ | ||||
1146 | 0 | $_.= ",$authid"; | ||||
1147 | } | |||||
1148 | 0 | @globalresult = (@globalresult,@trees); | ||||
1149 | 0 | $found=1; | ||||
1150 | } | |||||
1151 | 0 | $hierarchies=join(";",@globalresult); | ||||
1152 | } | |||||
1153 | #Unless there is no ancestor, I am alone. | |||||
1154 | 0 | $hierarchies="$authid" unless ($hierarchies); | ||||
1155 | } | |||||
1156 | 0 | AddAuthorityTrees($authid,$hierarchies); | ||||
1157 | 0 | return $hierarchies; | ||||
1158 | } | |||||
1159 | ||||||
1160 - 1177 | =head2 BuildUnimarcHierarchy $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. =cut | |||||
1178 | ||||||
1179 | sub BuildUnimarcHierarchy{ | |||||
1180 | 0 | my $record = shift @_; | ||||
1181 | 0 | my $class = shift @_; | ||||
1182 | 0 | my $authid_constructed = shift @_; | ||||
1183 | 0 | return undef unless ($record); | ||||
1184 | 0 | my $authid=$record->field('001')->data(); | ||||
1185 | 0 | my %cell; | ||||
1186 | 0 0 | my $parents=""; my $children=""; | ||||
1187 | 0 | my (@loopparents,@loopchildren); | ||||
1188 | 0 | foreach my $field ($record->field('5..')){ | ||||
1189 | 0 | my $subfauthid=_get_authid_subfield($field); | ||||
1190 | 0 | if ($subfauthid && $field->subfield('5') && $field->subfield('a')){ | ||||
1191 | 0 | if ($field->subfield('5') eq 'h'){ | ||||
1192 | 0 | push @loopchildren, { "childauthid"=>$field->subfield('3'),"childvalue"=>$field->subfield('a')}; | ||||
1193 | } | |||||
1194 | elsif ($field->subfield('5') eq 'g'){ | |||||
1195 | 0 | push @loopparents, { "parentauthid"=>$field->subfield('3'),"parentvalue"=>$field->subfield('a')}; | ||||
1196 | } | |||||
1197 | # brothers could get in there with an else | |||||
1198 | } | |||||
1199 | } | |||||
1200 | 0 | $cell{"ifparents"}=1 if (scalar(@loopparents)>0); | ||||
1201 | 0 | $cell{"ifchildren"}=1 if (scalar(@loopchildren)>0); | ||||
1202 | 0 | $cell{"loopparents"}=\@loopparents if (scalar(@loopparents)>0); | ||||
1203 | 0 | $cell{"loopchildren"}=\@loopchildren if (scalar(@loopchildren)>0); | ||||
1204 | 0 | $cell{"class"}=$class; | ||||
1205 | 0 | $cell{"loopauthid"}=$authid; | ||||
1206 | 0 | $cell{"current_value"} =1 if $authid eq $authid_constructed; | ||||
1207 | 0 | $cell{"value"}=$record->subfield('2..',"a"); | ||||
1208 | 0 | return \%cell; | ||||
1209 | } | |||||
1210 | ||||||
1211 | sub _get_authid_subfield{ | |||||
1212 | 0 | my ($field)=@_; | ||||
1213 | 0 | return $field->subfield('9')||$field->subfield('3'); | ||||
1214 | } | |||||
1215 - 1221 | =head2 GetHeaderAuthority $ref= &GetHeaderAuthority( $authid) return a hashref in order auth_header table data =cut | |||||
1222 | ||||||
1223 | sub GetHeaderAuthority{ | |||||
1224 | 0 | my $authid = shift @_; | ||||
1225 | 0 | my $sql= "SELECT * from auth_header WHERE authid = ?"; | ||||
1226 | 0 | my $dbh=C4::Context->dbh; | ||||
1227 | 0 | my $rq= $dbh->prepare($sql); | ||||
1228 | 0 | $rq->execute($authid); | ||||
1229 | 0 | my $data= $rq->fetchrow_hashref; | ||||
1230 | 0 | return $data; | ||||
1231 | } | |||||
1232 | ||||||
1233 - 1239 | =head2 AddAuthorityTrees $ref= &AddAuthorityTrees( $authid, $trees) return success or failure =cut | |||||
1240 | ||||||
1241 | sub AddAuthorityTrees{ | |||||
1242 | 0 | my $authid = shift @_; | ||||
1243 | 0 | my $trees = shift @_; | ||||
1244 | 0 | my $sql= "UPDATE IGNORE auth_header set authtrees=? WHERE authid = ?"; | ||||
1245 | 0 | my $dbh=C4::Context->dbh; | ||||
1246 | 0 | my $rq= $dbh->prepare($sql); | ||||
1247 | 0 | return $rq->execute($trees,$authid); | ||||
1248 | } | |||||
1249 | ||||||
1250 - 1257 | =head2 merge $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 =cut | |||||
1258 | ||||||
1259 | sub merge { | |||||
1260 | 0 | my ($mergefrom,$MARCfrom,$mergeto,$MARCto) = @_; | ||||
1261 | 0 | my ($counteditedbiblio,$countunmodifiedbiblio,$counterrors)=(0,0,0); | ||||
1262 | 0 | my $dbh=C4::Context->dbh; | ||||
1263 | 0 | my $authtypecodefrom = GetAuthTypeCode($mergefrom); | ||||
1264 | 0 | my $authtypecodeto = GetAuthTypeCode($mergeto); | ||||
1265 | # warn "mergefrom : $authtypecodefrom $mergefrom mergeto : $authtypecodeto $mergeto "; | |||||
1266 | # return if authority does not exist | |||||
1267 | 0 | return "error MARCFROM not a marcrecord ".Data::Dumper::Dumper($MARCfrom) if scalar($MARCfrom->fields()) == 0; | ||||
1268 | 0 | return "error MARCTO not a marcrecord".Data::Dumper::Dumper($MARCto) if scalar($MARCto->fields()) == 0; | ||||
1269 | # search the tag to report | |||||
1270 | 0 | my $sth = $dbh->prepare("select auth_tag_to_report from auth_types where authtypecode=?"); | ||||
1271 | 0 | $sth->execute($authtypecodefrom); | ||||
1272 | 0 | my ($auth_tag_to_report_from) = $sth->fetchrow; | ||||
1273 | 0 | $sth->execute($authtypecodeto); | ||||
1274 | 0 | my ($auth_tag_to_report_to) = $sth->fetchrow; | ||||
1275 | ||||||
1276 | 0 | my @record_to; | ||||
1277 | 0 | @record_to = $MARCto->field($auth_tag_to_report_to)->subfields() if $MARCto->field($auth_tag_to_report_to); | ||||
1278 | 0 | my @record_from; | ||||
1279 | 0 | @record_from = $MARCfrom->field($auth_tag_to_report_from)->subfields() if $MARCfrom->field($auth_tag_to_report_from); | ||||
1280 | ||||||
1281 | 0 | my @reccache; | ||||
1282 | # search all biblio tags using this authority. | |||||
1283 | #Getting marcbiblios impacted by the change. | |||||
1284 | 0 | if (C4::Context->preference('NoZebra')) { | ||||
1285 | #nozebra way | |||||
1286 | 0 | my $dbh=C4::Context->dbh; | ||||
1287 | 0 | my $rq=$dbh->prepare(qq(SELECT biblionumbers from nozebra where indexname="an" and server="biblioserver" and value="$mergefrom" )); | ||||
1288 | 0 | $rq->execute; | ||||
1289 | 0 | while (my $biblionumbers=$rq->fetchrow){ | ||||
1290 | 0 | my @biblionumbers=split /;/,$biblionumbers; | ||||
1291 | 0 | foreach (@biblionumbers) { | ||||
1292 | 0 | if ($_=~/(\d+),.*/) { | ||||
1293 | 0 | my $marc=GetMarcBiblio($1); | ||||
1294 | 0 | push @reccache,$marc; | ||||
1295 | } | |||||
1296 | } | |||||
1297 | } | |||||
1298 | } else { | |||||
1299 | #zebra connection | |||||
1300 | 0 | my $oConnection=C4::Context->Zconn("biblioserver",0); | ||||
1301 | 0 | my $oldSyntax = $oConnection->option("preferredRecordSyntax"); | ||||
1302 | 0 | $oConnection->option("preferredRecordSyntax"=>"XML"); | ||||
1303 | 0 | my $query; | ||||
1304 | 0 | $query= "an=".$mergefrom; | ||||
1305 | 0 | my $oResult = $oConnection->search(new ZOOM::Query::CCL2RPN( $query, $oConnection )); | ||||
1306 | 0 | my $count = 0; | ||||
1307 | 0 | if ($oResult) { | ||||
1308 | 0 | $count=$oResult->size(); | ||||
1309 | } | |||||
1310 | 0 | my $z=0; | ||||
1311 | 0 | while ( $z<$count ) { | ||||
1312 | 0 | my $rec; | ||||
1313 | 0 | $rec=$oResult->record($z); | ||||
1314 | 0 | my $marcdata = $rec->raw(); | ||||
1315 | 0 | my $marcrecordzebra= MARC::Record->new_from_xml($marcdata,"utf8",C4::Context->preference("marcflavour")); | ||||
1316 | 0 | my ( $biblionumbertagfield, $biblionumbertagsubfield ) = &GetMarcFromKohaField( "biblio.biblionumber", '' ); | ||||
1317 | 0 | my $i = $marcrecordzebra->subfield($biblionumbertagfield, $biblionumbertagsubfield); | ||||
1318 | 0 | my $marcrecorddb=GetMarcBiblio($i); | ||||
1319 | 0 | push @reccache, $marcrecorddb; | ||||
1320 | 0 | $z++; | ||||
1321 | } | |||||
1322 | 0 | $oResult->destroy(); | ||||
1323 | 0 | $oConnection->option("preferredRecordSyntax"=>$oldSyntax); | ||||
1324 | } | |||||
1325 | #warn scalar(@reccache)." biblios to update"; | |||||
1326 | # Get All candidate Tags for the change | |||||
1327 | # (This will reduce the search scope in marc records). | |||||
1328 | 0 | $sth = $dbh->prepare("select distinct tagfield from marc_subfield_structure where authtypecode=?"); | ||||
1329 | 0 | $sth->execute($authtypecodefrom); | ||||
1330 | 0 | my @tags_using_authtype; | ||||
1331 | 0 | while (my ($tagfield) = $sth->fetchrow) { | ||||
1332 | 0 | push @tags_using_authtype,$tagfield ; | ||||
1333 | } | |||||
1334 | 0 | my $tag_to=0; | ||||
1335 | 0 | if ($authtypecodeto ne $authtypecodefrom){ | ||||
1336 | # If many tags, take the first | |||||
1337 | 0 | $sth->execute($authtypecodeto); | ||||
1338 | 0 | $tag_to=$sth->fetchrow; | ||||
1339 | #warn $tag_to; | |||||
1340 | } | |||||
1341 | # BulkEdit marc records | |||||
1342 | # May be used as a template for a bulkedit field | |||||
1343 | 0 | foreach my $marcrecord(@reccache){ | ||||
1344 | 0 | my $update; | ||||
1345 | 0 | foreach my $tagfield (@tags_using_authtype){ | ||||
1346 | # warn "tagfield : $tagfield "; | |||||
1347 | 0 | foreach my $field ($marcrecord->field($tagfield)){ | ||||
1348 | 0 | my $auth_number=$field->subfield("9"); | ||||
1349 | 0 | my $tag=$field->tag(); | ||||
1350 | 0 | if ($auth_number==$mergefrom) { | ||||
1351 | 0 | my $field_to=MARC::Field->new(($tag_to?$tag_to:$tag),$field->indicator(1),$field->indicator(2),"9"=>$mergeto); | ||||
1352 | 0 | my $exclude='9'; | ||||
1353 | 0 | foreach my $subfield (@record_to) { | ||||
1354 | 0 | $field_to->add_subfields($subfield->[0] =>$subfield->[1]); | ||||
1355 | 0 | $exclude.= $subfield->[0]; | ||||
1356 | } | |||||
1357 | 0 | $exclude='['.$exclude.']'; | ||||
1358 | # add subfields in $field not included in @record_to | |||||
1359 | 0 0 | my @restore= grep {$_->[0]!~/$exclude/} $field->subfields(); | ||||
1360 | 0 | foreach my $subfield (@restore) { | ||||
1361 | 0 | $field_to->add_subfields($subfield->[0] =>$subfield->[1]); | ||||
1362 | } | |||||
1363 | 0 | $marcrecord->delete_field($field); | ||||
1364 | 0 | $marcrecord->insert_grouped_field($field_to); | ||||
1365 | 0 | $update=1; | ||||
1366 | } | |||||
1367 | }#for each tag | |||||
1368 | }#foreach tagfield | |||||
1369 | 0 | my ($bibliotag,$bibliosubf) = GetMarcFromKohaField("biblio.biblionumber","") ; | ||||
1370 | 0 | my $biblionumber; | ||||
1371 | 0 | if ($bibliotag<10){ | ||||
1372 | 0 | $biblionumber=$marcrecord->field($bibliotag)->data; | ||||
1373 | } | |||||
1374 | else { | |||||
1375 | 0 | $biblionumber=$marcrecord->subfield($bibliotag,$bibliosubf); | ||||
1376 | } | |||||
1377 | 0 | unless ($biblionumber){ | ||||
1378 | 0 | warn "pas de numéro de notice bibliographique dans : ".$marcrecord->as_formatted; | ||||
1379 | 0 | next; | ||||
1380 | } | |||||
1381 | 0 | if ($update==1){ | ||||
1382 | 0 | &ModBiblio($marcrecord,$biblionumber,GetFrameworkCode($biblionumber)) ; | ||||
1383 | 0 | $counteditedbiblio++; | ||||
1384 | 0 | warn $counteditedbiblio if (($counteditedbiblio % 10) and $ENV{DEBUG}); | ||||
1385 | } | |||||
1386 | }#foreach $marc | |||||
1387 | 0 | return $counteditedbiblio; | ||||
1388 | # now, find every other authority linked with this authority | |||||
1389 | # now, find every other authority linked with this authority | |||||
1390 | # my $oConnection=C4::Context->Zconn("authorityserver"); | |||||
1391 | # my $query; | |||||
1392 | # # att 9210 Auth-Internal-authtype | |||||
1393 | # # att 9220 Auth-Internal-LN | |||||
1394 | # # ccl.properties to add for authorities | |||||
1395 | # $query= "= ".$mergefrom; | |||||
1396 | # my $oResult = $oConnection->search(new ZOOM::Query::CCL2RPN( $query, $oConnection )); | |||||
1397 | # my $count=$oResult->size() if ($oResult); | |||||
1398 | # my @reccache; | |||||
1399 | # my $z=0; | |||||
1400 | # while ( $z<$count ) { | |||||
1401 | # my $rec; | |||||
1402 | # $rec=$oResult->record($z); | |||||
1403 | # my $marcdata = $rec->raw(); | |||||
1404 | # push @reccache, $marcdata; | |||||
1405 | # $z++; | |||||
1406 | # } | |||||
1407 | # $oResult->destroy(); | |||||
1408 | # foreach my $marc(@reccache){ | |||||
1409 | # my $update; | |||||
1410 | # my $marcrecord; | |||||
1411 | # $marcrecord = MARC::File::USMARC::decode($marc); | |||||
1412 | # foreach my $tagfield (@tags_using_authtype){ | |||||
1413 | # $tagfield=substr($tagfield,0,3); | |||||
1414 | # my @tags = $marcrecord->field($tagfield); | |||||
1415 | # foreach my $tag (@tags){ | |||||
1416 | # my $tagsubs=$tag->subfield("9"); | |||||
1417 | # #warn "$tagfield:$tagsubs:$mergefrom"; | |||||
1418 | # if ($tagsubs== $mergefrom) { | |||||
1419 | # $tag->update("9" =>$mergeto); | |||||
1420 | # foreach my $subfield (@record_to) { | |||||
1421 | # # warn "$subfield,$subfield->[0],$subfield->[1]"; | |||||
1422 | # $tag->update($subfield->[0] =>$subfield->[1]); | |||||
1423 | # }#for $subfield | |||||
1424 | # } | |||||
1425 | # $marcrecord->delete_field($tag); | |||||
1426 | # $marcrecord->add_fields($tag); | |||||
1427 | # $update=1; | |||||
1428 | # }#for each tag | |||||
1429 | # }#foreach tagfield | |||||
1430 | # my $authoritynumber = TransformMarcToKoha($dbh,$marcrecord,"") ; | |||||
1431 | # if ($update==1){ | |||||
1432 | # &ModAuthority($marcrecord,$authoritynumber,GetAuthTypeCode($authoritynumber)) ; | |||||
1433 | # } | |||||
1434 | # | |||||
1435 | # }#foreach $marc | |||||
1436 | }#sub | |||||
1437 | ||||||
1438 - 1452 | =head2 get_auth_type_location my ($tag, $subfield) = get_auth_type_location($auth_type_code); 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 | |||||
1453 | ||||||
1454 | sub get_auth_type_location { | |||||
1455 | 0 | my $auth_type_code = @_ ? shift : ''; | ||||
1456 | ||||||
1457 | 0 | my ($tag, $subfield) = GetAuthMARCFromKohaField('auth_header.authtypecode', $auth_type_code); | ||||
1458 | 0 | if (defined $tag and defined $subfield and $tag != 0 and $subfield ne '' and $subfield ne ' ') { | ||||
1459 | 0 | return ($tag, $subfield); | ||||
1460 | } else { | |||||
1461 | 0 | if (C4::Context->preference('marcflavour') eq "MARC21") { | ||||
1462 | 0 | return C4::AuthoritiesMarc::MARC21::default_auth_type_location(); | ||||
1463 | } else { | |||||
1464 | 0 | return C4::AuthoritiesMarc::UNIMARC::default_auth_type_location(); | ||||
1465 | } | |||||
1466 | } | |||||
1467 | } | |||||
1468 | ||||||
1469 | 3 | 2479882 | END { } # module clean-up code here (global destructor) | |||
1470 | ||||||
1471 | 1; |