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