3 # Copyright 2000-2002 Katipo Communications
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along with
17 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18 # Suite 330, Boston, MA 02111-1307 USA
25 use MARC::File::USMARC;
28 use vars qw($VERSION @ISA @EXPORT);
30 # set the version for version checking
36 # don't forget MARCxxx subs are exported only for testing purposes. Should not be used
37 # as the old-style API and the NEW one are the only public functions.
40 &itemcount &newbiblio &newbiblioitem
41 &newsubject &newsubtitle
42 &modbiblio &checkitems
44 &modsubtitle &modsubject &modaddauthor &moditem
45 &delitem &deletebiblioitem &delbiblio
47 &getbiblioitembybiblionumber
48 &getbiblioitem &getitemsbybiblioitem
50 &MARCfind_marc_from_kohafield
51 &MARCfind_frameworkcode
52 &find_biblioitemnumber
55 &NEWnewbiblio &NEWnewitem
56 &NEWmodbiblio &NEWmoditem
57 &NEWdelbiblio &NEWdelitem
58 &NEWmodbiblioframework
60 &MARCkoha2marcBiblio &MARCmarc2koha
61 &MARCkoha2marcItem &MARChtml2marc
62 &MARCgetbiblio &MARCgetitem
71 C4::Biblio - acquisition, catalog management functions
75 ( lot of changes for Koha 3.0)
77 Koha 1.2 and previous version used a specific API to manage biblios. This API uses old-DB style parameters.
78 They are based on a hash, and store data in biblio/biblioitems/items tables (plus additionalauthors, bibliosubject and bibliosubtitle where applicable)
80 In Koha 2.0, we introduced a MARC-DB.
82 In Koha 3.0 we removed this MARC-DB for search as we wanted to use Zebra as search system.
84 So in Koha 3.0, saving a record means :
85 - storing the raw marc record (iso2709) in biblioitems.marc field. It contains both biblio & items informations.
86 - storing the "decoded information" in biblio/biblioitems/items as previously.
87 - using zebra to manage search & indexing on the MARC datas.
89 In Koha, there is a systempreference saying "MARC=ON" or "MARC=OFF"
91 * MARC=ON : when MARC=ON, koha uses a MARC::Record object (in sub parameters). Saving informations in the DB means :
92 - transform the MARC record into a hash
93 - add the raw marc record into the hash
94 - store them & update zebra
96 * MARC=OFF : when MARC=OFF, koha uses a hash object (in sub parameters). Saving informations in the DB means :
97 - transform the hash into a MARC record
98 - add the raw marc record into the hash
99 - store them and update zebra
102 That's why we need 3 types of subs :
106 all I<subs beginning by REAL> does effective storage of information (with a hash, one field of the hash being the raw marc record). Those subs also update the record in zebra. REAL subs should be only for internal use (called by NEW or "something else" subs
108 =head2 NEWxxx related subs
112 all I<subs beginning by NEW> use MARC::Record as parameters. it's the API that MUST be used in MARC acquisition system. They just create the hash, add it the raw marc record. Then, they call REALxxx sub.
114 all subs requires/use $dbh as 1st parameter and a MARC::Record object as 2nd parameter. they sometimes requires another parameter.
118 =head2 something_elsexxx related subs
122 all I<subs beginning by seomething else> are the old-style API. They use a hash as parameter, transform the hash into a -small- marc record, and calls REAL subs.
124 all subs requires/use $dbh as 1st parameter and a hash as 2nd parameter.
133 my ($biblionumber,$record) = @_;
134 # create the iso2709 file for zebra
135 my $cgidir = C4::Context->intranetdir ."/cgi-bin";
136 unless (opendir(DIR, "$cgidir")) {
137 $cgidir = C4::Context->intranetdir."/";
140 my $filename = $cgidir."/zebra/biblios/BIBLIO".$biblionumber."iso2709";
141 open F,"> $filename";
142 print F $record->as_usmarc();
144 my $res = system("cd $cgidir/zebra;/usr/local/bin/zebraidx update biblios");
146 warn "$biblionumber : $res";
149 =head2 @tagslib = &MARCgettagslib($dbh,1|0,$frameworkcode);
153 2nd param is 1 for liblibrarian and 0 for libopac
154 $frameworkcode contains the framework reference. If empty or does not exist, the default one is used
156 returns a hash with all values for all fields and subfields for a given MARC framework :
157 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
159 ->{mandatory} = $mandatory;
160 ->{repeatable} = $repeatable;
161 ->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
163 ->{mandatory} = $mandatory;
164 ->{repeatable} = $repeatable;
165 ->{authorised_value} = $authorised_value;
166 ->{authtypecode} = $authtypecode;
167 ->{value_builder} = $value_builder;
168 ->{kohafield} = $kohafield;
169 ->{seealso} = $seealso;
170 ->{hidden} = $hidden;
179 my ( $dbh, $forlibrarian, $frameworkcode ) = @_;
180 $frameworkcode = "" unless $frameworkcode;
182 my $libfield = ( $forlibrarian eq 1 ) ? 'liblibrarian' : 'libopac';
184 # check that framework exists
187 "select count(*) from marc_tag_structure where frameworkcode=?");
188 $sth->execute($frameworkcode);
189 my ($total) = $sth->fetchrow;
190 $frameworkcode = "" unless ( $total > 0 );
193 "select tagfield,liblibrarian,libopac,mandatory,repeatable from marc_tag_structure where frameworkcode=? order by tagfield"
195 $sth->execute($frameworkcode);
196 my ( $liblibrarian, $libopac, $tag, $res, $tab, $mandatory, $repeatable );
198 while ( ( $tag, $liblibrarian, $libopac, $mandatory, $repeatable ) = $sth->fetchrow ) {
199 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
200 $res->{$tab}->{tab} = ""; # XXX
201 $res->{$tag}->{mandatory} = $mandatory;
202 $res->{$tag}->{repeatable} = $repeatable;
207 "select tagfield,tagsubfield,liblibrarian,libopac,tab, mandatory, repeatable,authorised_value,authtypecode,value_builder,kohafield,seealso,hidden,isurl,link from marc_subfield_structure where frameworkcode=? order by tagfield,tagsubfield"
209 $sth->execute($frameworkcode);
212 my $authorised_value;
222 ( $tag, $subfield, $liblibrarian, , $libopac, $tab,
223 $mandatory, $repeatable, $authorised_value, $authtypecode,
224 $value_builder, $kohafield, $seealso, $hidden,
229 $res->{$tag}->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
230 $res->{$tag}->{$subfield}->{tab} = $tab;
231 $res->{$tag}->{$subfield}->{mandatory} = $mandatory;
232 $res->{$tag}->{$subfield}->{repeatable} = $repeatable;
233 $res->{$tag}->{$subfield}->{authorised_value} = $authorised_value;
234 $res->{$tag}->{$subfield}->{authtypecode} = $authtypecode;
235 $res->{$tag}->{$subfield}->{value_builder} = $value_builder;
236 $res->{$tag}->{$subfield}->{kohafield} = $kohafield;
237 $res->{$tag}->{$subfield}->{seealso} = $seealso;
238 $res->{$tag}->{$subfield}->{hidden} = $hidden;
239 $res->{$tag}->{$subfield}->{isurl} = $isurl;
240 $res->{$tag}->{$subfield}->{link} = $link;
245 =head2 ($tagfield,$tagsubfield) = &MARCfind_marc_from_kohafield($dbh,$kohafield);
249 finds MARC tag and subfield for a given kohafield
250 kohafield is "table.field" where table= biblio|biblioitems|items, and field a field of the previous table
256 sub MARCfind_marc_from_kohafield {
257 my ( $dbh, $kohafield,$frameworkcode ) = @_;
258 return 0, 0 unless $kohafield;
259 my $relations = C4::Context->marcfromkohafield;
260 return ($relations->{$frameworkcode}->{$kohafield}->[0],$relations->{$frameworkcode}->{$kohafield}->[1]);
263 =head2 $MARCRecord = &MARCgetbiblio($dbh,$biblionumber);
267 Returns a MARC::Record for the biblio $biblionumber.
273 # Returns MARC::Record of the biblio passed in parameter.
274 my ( $dbh, $biblionumber ) = @_;
275 my $sth = $dbh->prepare('select marc from biblioitems where biblionumber=?');
276 $sth->execute($biblionumber);
277 my ($marc) = $sth->fetchrow;
278 my $record = MARC::File::USMARC::decode($marc);
282 =head2 $MARCrecord = &MARCgetitem($dbh,$biblionumber);
286 Returns a MARC::Record with all items of biblio # $biblionumber
294 my ( $dbh, $biblionumber, $itemnumber ) = @_;
295 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
296 # get the complete MARC record
297 my $sth = $dbh->prepare("select marc from biblioitems where biblionumber=?");
298 $sth->execute($biblionumber);
299 my ($rawmarc) = $sth->fetchrow;
300 my $record = MARC::File::USMARC::decode($rawmarc);
301 # now, find the relevant itemnumber
302 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
303 # prepare the new item record
304 my $itemrecord = MARC::Record->new();
305 # parse all fields fields from the complete record
306 foreach ($record->field($itemnumberfield)) {
307 # when the item field is found, save it
308 if ($_->subfield($itemnumbersubfield) == $itemnumber) {
309 $itemrecord->append_fields($_);
316 =head2 sub find_biblioitemnumber($dbh,$biblionumber);
320 Returns the 1st biblioitemnumber related to $biblionumber. When MARC=ON we should have 1 biblionumber = 1 and only 1 biblioitemnumber
321 This sub is useless when MARC=OFF
326 sub find_biblioitemnumber {
327 my ( $dbh, $biblionumber ) = @_;
328 my $sth = $dbh->prepare("select biblioitemnumber from biblioitems where biblionumber=?");
329 $sth->execute($biblionumber);
330 my ($biblioitemnumber) = $sth->fetchrow;
331 return $biblioitemnumber;
334 =head2 $frameworkcode = MARCfind_frameworkcode($dbh,$biblionumber);
338 returns the framework of a given biblio
344 sub MARCfind_frameworkcode {
345 my ( $dbh, $biblionumber ) = @_;
346 my $sth = $dbh->prepare("select frameworkcode from biblio where biblionumber=?");
347 $sth->execute($biblionumber);
348 my ($frameworkcode) = $sth->fetchrow;
349 return $frameworkcode;
352 =head2 $MARCRecord = &MARCkoha2marcBiblio($dbh,$biblionumber,biblioitemnumber);
356 MARCkoha2marcBiblio is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB biblio/biblioitem :
357 all entries of the hash are transformed into their matching MARC field/subfield.
363 sub MARCkoha2marcBiblio {
365 # this function builds partial MARC::Record from the old koha-DB fields
366 my ( $dbh, $biblionumber, $biblioitemnumber ) = @_;
369 "select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?"
371 my $record = MARC::Record->new();
373 #--- if bibid, then retrieve old-style koha data
374 if ( $biblionumber > 0 ) {
377 "select biblionumber,author,title,unititle,notes,abstract,serial,seriestitle,copyrightdate,timestamp
378 from biblio where biblionumber=?"
380 $sth2->execute($biblionumber);
381 my $row = $sth2->fetchrow_hashref;
383 foreach $code ( keys %$row ) {
384 if ( $row->{$code} ) {
385 &MARCkoha2marcOnefield( $sth, $record, "biblio." . $code,
391 #--- if biblioitem, then retrieve old-style koha data
392 if ( $biblioitemnumber > 0 ) {
395 " SELECT biblioitemnumber,biblionumber,volume,number,classification,
396 itemtype,url,isbn,issn,dewey,subclass,publicationyear,publishercode,
397 volumedate,volumeddesc,timestamp,illus,pages,notes AS bnotes,size,place
399 WHERE biblioitemnumber=?
402 $sth2->execute($biblioitemnumber);
403 my $row = $sth2->fetchrow_hashref;
405 foreach $code ( keys %$row ) {
406 if ( $row->{$code} ) {
407 &MARCkoha2marcOnefield( $sth, $record, "biblioitems." . $code,
413 # other fields => additional authors, subjects, subtitles
416 " SELECT author FROM additionalauthors WHERE biblionumber=?");
417 $sth2->execute($biblionumber);
418 while ( my $row = $sth2->fetchrow_hashref ) {
419 &MARCkoha2marcOnefield( $sth, $record, "additionalauthors.author",
420 $row->{'author'},'' );
423 $dbh->prepare(" SELECT subject FROM bibliosubject WHERE biblionumber=?");
424 $sth2->execute($biblionumber);
425 while ( my $row = $sth2->fetchrow_hashref ) {
426 &MARCkoha2marcOnefield( $sth, $record, "bibliosubject.subject",
427 $row->{'subject'},'' );
431 " SELECT subtitle FROM bibliosubtitle WHERE biblionumber=?");
432 $sth2->execute($biblionumber);
433 while ( my $row = $sth2->fetchrow_hashref ) {
434 &MARCkoha2marcOnefield( $sth, $record, "bibliosubtitle.subtitle",
435 $row->{'subtitle'},'' );
440 =head2 $MARCRecord = &MARCkoha2marcItem($dbh,$biblionumber,itemnumber);
442 MARCkoha2marcItem is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB items :
443 all entries of the hash are transformed into their matching MARC field/subfield.
451 sub MARCkoha2marcItem {
453 # this function builds partial MARC::Record from the old koha-DB fields
454 my ( $dbh, $biblionumber, $itemnumber ) = @_;
456 # my $dbh=&C4Connect;
459 "select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?"
461 my $record = MARC::Record->new();
463 #--- if item, then retrieve old-style koha data
464 if ( $itemnumber > 0 ) {
466 # print STDERR "prepare $biblionumber,$itemnumber\n";
469 "SELECT itemnumber,biblionumber,multivolumepart,biblioitemnumber,barcode,dateaccessioned,
470 booksellerid,homebranch,price,replacementprice,replacementpricedate,datelastborrowed,
471 datelastseen,multivolume,stack,notforloan,itemlost,wthdrawn,itemcallnumber,issues,renewals,
472 reserves,restricted,binding,itemnotes,holdingbranch,timestamp
476 $sth2->execute($itemnumber);
477 my $row = $sth2->fetchrow_hashref;
479 foreach $code ( keys %$row ) {
480 if ( $row->{$code} ) {
481 &MARCkoha2marcOnefield( $sth, $record, "items." . $code,
489 =head2 MARCkoha2marcOnefield
493 This sub is for internal use only, used by koha2marcBiblio & koha2marcItem
499 sub MARCkoha2marcOnefield {
500 my ( $sth, $record, $kohafieldname, $value,$frameworkcode ) = @_;
503 $sth->execute($frameworkcode,$kohafieldname);
504 if ( ( $tagfield, $tagsubfield ) = $sth->fetchrow ) {
505 if ( $record->field($tagfield) ) {
506 my $tag = $record->field($tagfield);
508 $tag->add_subfields( $tagsubfield, $value );
509 $record->delete_field($tag);
510 $record->add_fields($tag);
514 $record->add_fields( $tagfield, " ", " ", $tagsubfield => $value );
520 =head2 $MARCrecord = MARChtml2marc($dbh,$rtags,$rsubfields,$rvalues,%indicators);
524 transforms the parameters (coming from HTML form) into a MARC::Record
525 parameters with r are references to arrays.
527 FIXME : should be improved for 3.0, to avoid having 4 differents arrays
534 my ($dbh,$rtags,$rsubfields,$rvalues,%indicators) = @_;
536 my $record = MARC::Record->new();
537 # my %subfieldlist=();
538 my $prevvalue; # if tag <10
539 my $field; # if tag >=10
540 for (my $i=0; $i< @$rtags; $i++) {
541 next unless @$rvalues[$i];
542 # rebuild MARC::Record
543 # warn "0=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ";
544 if (@$rtags[$i] ne $prevtag) {
547 if ($prevtag ne '000') {
548 $record->add_fields((sprintf "%03s",$prevtag),$prevvalue);
550 $record->leader($prevvalue);
555 $record->add_fields($field);
558 $indicators{@$rtags[$i]}.=' ';
559 if (@$rtags[$i] <10) {
560 $prevvalue= @$rvalues[$i];
564 $field = MARC::Field->new( (sprintf "%03s",@$rtags[$i]), substr($indicators{@$rtags[$i]},0,1),substr($indicators{@$rtags[$i]},1,1), @$rsubfields[$i] => @$rvalues[$i]);
565 # warn "1=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ".$field->as_formatted;
567 $prevtag = @$rtags[$i];
569 if (@$rtags[$i] <10) {
570 $prevvalue=@$rvalues[$i];
572 if (length(@$rvalues[$i])>0) {
573 $field->add_subfields(@$rsubfields[$i] => @$rvalues[$i]);
574 # warn "2=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ".$field->as_formatted;
577 $prevtag= @$rtags[$i];
580 # the last has not been included inside the loop... do it now !
581 $record->add_fields($field) if $field;
582 # warn "HTML2MARC=".$record->as_formatted;
587 =head2 $hash = &MARCmarc2koha($dbh,$MARCRecord);
591 builds a hash with old-db datas from a MARC::Record
598 my ($dbh,$record,$frameworkcode) = @_;
599 my $sth=$dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
601 my $sth2=$dbh->prepare("SHOW COLUMNS from biblio");
604 while (($field)=$sth2->fetchrow) {
605 $result=&MARCmarc2kohaOneField($sth,"biblio",$field,$record,$result,$frameworkcode);
607 $sth2=$dbh->prepare("SHOW COLUMNS from biblioitems");
609 while (($field)=$sth2->fetchrow) {
610 if ($field eq 'notes') { $field = 'bnotes'; }
611 $result=&MARCmarc2kohaOneField($sth,"biblioitems",$field,$record,$result,$frameworkcode);
613 $sth2=$dbh->prepare("SHOW COLUMNS from items");
615 while (($field)=$sth2->fetchrow) {
616 $result=&MARCmarc2kohaOneField($sth,"items",$field,$record,$result,$frameworkcode);
618 # additional authors : specific
619 $result = &MARCmarc2kohaOneField($sth,"bibliosubtitle","subtitle",$record,$result,$frameworkcode);
620 $result = &MARCmarc2kohaOneField($sth,"additionalauthors","additionalauthors",$record,$result,$frameworkcode);
621 # modify copyrightdate to keep only the 1st year found
622 my $temp = $result->{'copyrightdate'};
623 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
625 $result->{'copyrightdate'} = $1;
626 } else { # if no cYYYY, get the 1st date.
627 $temp =~ m/(\d\d\d\d)/;
628 $result->{'copyrightdate'} = $1;
630 # modify publicationyear to keep only the 1st year found
631 $temp = $result->{'publicationyear'};
632 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
634 $result->{'publicationyear'} = $1;
635 } else { # if no cYYYY, get the 1st date.
636 $temp =~ m/(\d\d\d\d)/;
637 $result->{'publicationyear'} = $1;
642 sub MARCmarc2kohaOneField {
644 # FIXME ? if a field has a repeatable subfield that is used in old-db, only the 1st will be retrieved...
645 my ( $sth, $kohatable, $kohafield, $record, $result,$frameworkcode ) = @_;
646 # warn "kohatable / $kohafield / $result / ";
650 ( $tagfield, $subfield ) = MARCfind_marc_from_kohafield("",$kohatable.".".$kohafield,$frameworkcode);
651 foreach my $field ( $record->field($tagfield) ) {
652 if ($field->tag()<10) {
653 if ($result->{$kohafield}) {
654 $result->{$kohafield} .= " | ".$field->data();
656 $result->{$kohafield} = $field->data();
659 if ( $field->subfields ) {
660 my @subfields = $field->subfields();
661 foreach my $subfieldcount ( 0 .. $#subfields ) {
662 if ($subfields[$subfieldcount][0] eq $subfield) {
663 if ( $result->{$kohafield} ) {
664 $result->{$kohafield} .= " | " . $subfields[$subfieldcount][1];
667 $result->{$kohafield} = $subfields[$subfieldcount][1];
674 # warn "OneField for $kohatable.$kohafield and $frameworkcode=> $tagfield, $subfield";
678 =head2 ($biblionumber,$biblioitemnumber) = NEWnewbibilio($dbh,$MARCRecord,$frameworkcode);
682 creates a biblio from a MARC::Record.
689 my ( $dbh, $record, $frameworkcode ) = @_;
691 my $biblioitemnumber;
692 my $olddata = MARCmarc2koha( $dbh, $record,$frameworkcode );
693 $olddata->{frameworkcode} = $frameworkcode;
694 $biblionumber = REALnewbiblio( $dbh, $olddata );
695 $olddata->{biblionumber} = $biblionumber;
696 # add biblionumber into the MARC record (it's the ID for zebra)
697 my ( $tagfield, $tagsubfield ) =
698 MARCfind_marc_from_kohafield( $dbh, "biblio.biblionumber",$frameworkcode );
702 $newfield = MARC::Field->new(
703 $tagfield, $biblionumber,
706 $newfield = MARC::Field->new(
707 $tagfield, '', '', "$tagsubfield" => $biblionumber,
710 # drop old field (just in case it already exist and create new one...
711 my $old_field = $record->field($tagfield);
712 $record->delete_field($old_field);
713 $record->add_fields($newfield);
715 #create the marc entry, that stores the rax marc record in Koha 3.0
716 $olddata->{marc} = $record->as_usmarc();
717 $olddata->{marcxml} = $record->as_xml();
718 # and create biblioitem, that's all folks !
719 $biblioitemnumber = REALnewbiblioitem( $dbh, $olddata );
721 # search subtiles, addiauthors and subjects
722 ( $tagfield, $tagsubfield ) =
723 MARCfind_marc_from_kohafield( $dbh, "additionalauthors.author",$frameworkcode );
724 my @addiauthfields = $record->field($tagfield);
725 foreach my $addiauthfield (@addiauthfields) {
726 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
727 foreach my $subfieldcount ( 0 .. $#addiauthsubfields ) {
728 REALmodaddauthor( $dbh, $biblionumber,
729 $addiauthsubfields[$subfieldcount] );
732 ( $tagfield, $tagsubfield ) =
733 MARCfind_marc_from_kohafield( $dbh, "bibliosubtitle.subtitle",$frameworkcode );
734 my @subtitlefields = $record->field($tagfield);
735 foreach my $subtitlefield (@subtitlefields) {
736 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
737 foreach my $subfieldcount ( 0 .. $#subtitlesubfields ) {
738 REALnewsubtitle( $dbh, $biblionumber,
739 $subtitlesubfields[$subfieldcount] );
742 ( $tagfield, $tagsubfield ) =
743 MARCfind_marc_from_kohafield( $dbh, "bibliosubject.subject",$frameworkcode );
744 my @subj = $record->field($tagfield);
746 foreach my $subject (@subj) {
747 my @subjsubfield = $subject->subfield($tagsubfield);
748 foreach my $subfieldcount ( 0 .. $#subjsubfield ) {
749 push @subjects, $subjsubfield[$subfieldcount];
752 REALmodsubject( $dbh, $biblionumber, 1, @subjects );
753 return ( $biblionumber, $biblioitemnumber );
756 =head2 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
760 modify the framework of a biblio
766 sub NEWmodbiblioframework {
767 my ($dbh,$biblionumber,$frameworkcode) =@_;
768 my $sth = $dbh->prepare("Update biblio SET frameworkcode=? WHERE biblionumber=?");
769 $sth->execute($frameworkcode,$biblionumber);
773 =head2 NEWmodbiblio($dbh,$MARCrecord,$biblionumber,$frameworkcode);
777 modify a biblio (MARC=ON)
784 my ($dbh,$record,$biblionumber,$frameworkcode) =@_;
785 $frameworkcode="" unless $frameworkcode;
786 # &MARCmodbiblio($dbh,$bibid,$record,$frameworkcode,0);
787 my $oldbiblio = MARCmarc2koha($dbh,$record,$frameworkcode);
789 $oldbiblio->{frameworkcode} = $frameworkcode;
790 #create the marc entry, that stores the rax marc record in Koha 3.0
791 $oldbiblio->{marc} = $record->as_usmarc();
792 $oldbiblio->{marcxml} = $record->as_xml();
794 REALmodbiblio($dbh,$oldbiblio);
795 REALmodbiblioitem($dbh,$oldbiblio);
796 # now, modify addi authors, subject, addititles.
797 my ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"additionalauthors.author",$frameworkcode);
798 my @addiauthfields = $record->field($tagfield);
799 foreach my $addiauthfield (@addiauthfields) {
800 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
801 foreach my $subfieldcount (0..$#addiauthsubfields) {
802 REALmodaddauthor($dbh,$biblionumber,$addiauthsubfields[$subfieldcount]);
805 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubtitle.subtitle",$frameworkcode);
806 my @subtitlefields = $record->field($tagfield);
807 foreach my $subtitlefield (@subtitlefields) {
808 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
809 # delete & create subtitle again because REALmodsubtitle can't handle new subtitles
811 $dbh->do("delete from bibliosubtitle where biblionumber=$biblionumber");
812 foreach my $subfieldcount (0..$#subtitlesubfields) {
813 foreach my $subtit(split /\||#/,$subtitlesubfields[$subfieldcount]) {
814 REALnewsubtitle($dbh,$biblionumber,$subtit);
818 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubject.subject",$frameworkcode);
819 my @subj = $record->field($tagfield);
821 foreach my $subject (@subj) {
822 my @subjsubfield = $subject->subfield($tagsubfield);
823 foreach my $subfieldcount (0..$#subjsubfield) {
824 push @subjects,$subjsubfield[$subfieldcount];
827 REALmodsubject($dbh,$biblionumber,1,@subjects);
831 =head2 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
842 my ( $dbh, $bibid ) = @_;
843 my $biblio = &MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
844 &REALdelbiblio( $dbh, $biblio );
847 "select biblioitemnumber from biblioitems where biblionumber=?");
848 $sth->execute($biblio);
849 while ( my ($biblioitemnumber) = $sth->fetchrow ) {
850 REALdelbiblioitem( $dbh, $biblioitemnumber );
852 &MARCdelbiblio( $dbh, $bibid, 0 );
855 =head2 $itemnumber = NEWnewitem($dbh, $record, $biblionumber, $biblioitemnumber);
859 creates an item from a MARC::Record
866 my ( $dbh, $record, $biblionumber, $biblioitemnumber ) = @_;
869 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
870 my $item = &MARCmarc2koha( $dbh, $record,$frameworkcode );
871 # needs old biblionumber and biblioitemnumber
872 $item->{'biblionumber'} = $biblionumber;
873 $item->{'biblioitemnumber'}=$biblioitemnumber;
874 $item->{marc} = $record->as_usmarc();
875 my ( $itemnumber, $error ) = &REALnewitems( $dbh, $item, $item->{barcode} );
880 =head2 $itemnumber = NEWmoditem($dbh, $record, $biblionumber, $biblioitemnumber,$itemnumber);
891 my ( $dbh, $record, $biblionumber, $biblioitemnumber, $itemnumber) = @_;
893 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
894 my $olditem = MARCmarc2koha( $dbh, $record,$frameworkcode );
896 $olditem->{marc} = $record->as_usmarc();
897 $olditem->{biblionumber} = $biblionumber;
898 $olditem->{biblioitemnumber} = $biblioitemnumber;
900 REALmoditem( $dbh, $olditem );
904 =head2 $itemnumber = NEWdelitem($dbh, $biblionumber, $biblioitemnumber, $itemnumber);
915 my ( $dbh, $bibid, $itemnumber ) = @_;
916 my $biblio = &MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
917 &REALdelitem( $dbh, $itemnumber );
918 &MARCdelitem( $dbh, $bibid, $itemnumber );
922 =head2 $biblionumber = REALnewbiblio($dbh,$biblio);
926 adds a record in biblio table. Datas are in the hash $biblio.
933 my ( $dbh, $biblio ) = @_;
935 $dbh->do('lock tables biblio WRITE');
936 my $sth = $dbh->prepare("Select max(biblionumber) from biblio");
938 my $data = $sth->fetchrow_arrayref;
939 my $bibnum = $$data[0] + 1;
942 if ( $biblio->{'seriestitle'} ) { $series = 1 }
945 $dbh->prepare("insert into biblio set biblionumber=?, title=?, author=?, copyrightdate=?,
946 serial=?, seriestitle=?, notes=?, abstract=?,
950 $bibnum, $biblio->{'title'},
951 $biblio->{'author'}, $biblio->{'copyrightdate'},
952 $biblio->{'serial'}, $biblio->{'seriestitle'},
953 $biblio->{'notes'}, $biblio->{'abstract'},
954 $biblio->{'unititle'}
958 $dbh->do('unlock tables');
962 =head2 $biblionumber = REALmodbiblio($dbh,$biblio);
966 modify a record in biblio table. Datas are in the hash $biblio.
973 my ( $dbh, $biblio ) = @_;
974 my $sth = $dbh->prepare("Update biblio set title=?, author=?, abstract=?, copyrightdate=?,
975 seriestitle=?, serial=?, unititle=?, notes=?, frameworkcode=?
976 where biblionumber = ?"
979 $biblio->{'title'}, $biblio->{'author'},
980 $biblio->{'abstract'}, $biblio->{'copyrightdate'},
981 $biblio->{'seriestitle'}, $biblio->{'serial'},
982 $biblio->{'unititle'}, $biblio->{'notes'},
983 $biblio->{frameworkcode},
984 $biblio->{'biblionumber'}
987 return ( $biblio->{'biblionumber'} );
990 =head2 REALmodsubtitle($dbh,$bibnum,$subtitle);
994 modify subtitles in bibliosubtitle table.
1000 sub REALmodsubtitle {
1001 my ( $dbh, $bibnum, $subtitle ) = @_;
1004 "update bibliosubtitle set subtitle = ? where biblionumber = ?");
1005 $sth->execute( $subtitle, $bibnum );
1009 =head2 REALmodaddauthor($dbh,$bibnum,$author);
1013 adds or modify additional authors
1014 NOTE : Strange sub : seems to delete MANY and add only ONE author... maybe buggy ?
1020 sub REALmodaddauthor {
1021 my ( $dbh, $bibnum, @authors ) = @_;
1023 # my $dbh = C4Connect;
1025 $dbh->prepare("Delete from additionalauthors where biblionumber = ?");
1027 $sth->execute($bibnum);
1029 foreach my $author (@authors) {
1030 if ( $author ne '' ) {
1033 "Insert into additionalauthors set author = ?, biblionumber = ?"
1036 $sth->execute( $author, $bibnum );
1041 } # sub modaddauthor
1043 =head2 $errors = REALmodsubject($dbh,$bibnum, $force, @subject);
1047 modify/adds subjects
1052 sub REALmodsubject {
1053 my ( $dbh, $bibnum, $force, @subject ) = @_;
1055 # my $dbh = C4Connect;
1056 my $count = @subject;
1058 for ( my $i = 0 ; $i < $count ; $i++ ) {
1059 $subject[$i] =~ s/^ //g;
1060 $subject[$i] =~ s/ $//g;
1063 "select * from catalogueentry where entrytype = 's' and catalogueentry = ?"
1065 $sth->execute( $subject[$i] );
1067 if ( my $data = $sth->fetchrow_hashref ) {
1070 if ( $force eq $subject[$i] || $force == 1 ) {
1072 # subject not in aut, chosen to force anway
1073 # so insert into cataloguentry so its in auth file
1076 "Insert into catalogueentry (entrytype,catalogueentry) values ('s',?)"
1079 $sth2->execute( $subject[$i] ) if ( $subject[$i] );
1084 "$subject[$i]\n does not exist in the subject authority file";
1087 "Select * from catalogueentry where entrytype = 's' and (catalogueentry like ? or catalogueentry like ? or catalogueentry like ?)"
1089 $sth2->execute( "$subject[$i] %", "% $subject[$i] %",
1091 while ( my $data = $sth2->fetchrow_hashref ) {
1092 $error .= "<br>$data->{'catalogueentry'}";
1099 if ( $error eq '' ) {
1101 $dbh->prepare("Delete from bibliosubject where biblionumber = ?");
1102 $sth->execute($bibnum);
1106 "Insert into bibliosubject (subject,biblionumber) values (?,?)");
1108 foreach $query (@subject) {
1109 $sth->execute( $query, $bibnum ) if ( $query && $bibnum );
1118 =head2 REALmodbiblioitem($dbh, $biblioitem);
1127 sub REALmodbiblioitem {
1128 my ( $dbh, $biblioitem ) = @_;
1131 my $sth = $dbh->prepare("update biblioitems set itemtype=?, url=?, isbn=?, issn=?,
1132 publishercode=?, publicationyear=?, classification=?, dewey=?,
1133 subclass=?, illus=?, pages=?, volumeddesc=?,
1134 notes=?, size=?, place=?, marc=?,
1136 where biblioitemnumber=?");
1137 $sth->execute( $biblioitem->{itemtype}, $biblioitem->{url}, $biblioitem->{isbn}, $biblioitem->{issn},
1138 $biblioitem->{publishercode}, $biblioitem->{publicationyear}, $biblioitem->{classification}, $biblioitem->{dewey},
1139 $biblioitem->{subclass}, $biblioitem->{illus}, $biblioitem->{pages}, $biblioitem->{volumeddesc},
1140 $biblioitem->{bnotes}, $biblioitem->{size}, $biblioitem->{place}, $biblioitem->{marc},
1141 $biblioitem->{marcxml}, $biblioitem->{biblioitemnumber});
1142 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1143 zebra_create($biblioitem->{biblionumber}, $record);
1144 # warn "MOD : $biblioitem->{biblioitemnumber} = ".$biblioitem->{marc};
1147 =head2 REALnewbiblioitem($dbh,$biblioitem);
1151 adds a biblioitem ($biblioitem is a hash with the values)
1157 sub REALnewbiblioitem {
1158 my ( $dbh, $biblioitem ) = @_;
1160 $dbh->do("lock tables biblioitems WRITE, biblio WRITE");
1161 my $sth = $dbh->prepare("Select max(biblioitemnumber) from biblioitems");
1163 my $biblioitemnumber;
1166 $data = $sth->fetchrow_arrayref;
1167 $biblioitemnumber = $$data[0] + 1;
1169 # Insert biblioitemnumber in MARC record, we need it to manage items later...
1170 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblioitem->{biblionumber});
1171 my ($biblioitemnumberfield,$biblioitemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'biblioitems.biblioitemnumber',$frameworkcode);
1172 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1173 my $field=$record->field($biblioitemnumberfield);
1174 $field->update($biblioitemnumbersubfield => "$biblioitemnumber");
1175 $biblioitem->{marc} = $record->as_usmarc();
1176 $biblioitem->{marcxml} = $record->as_xml();
1178 $sth = $dbh->prepare( "insert into biblioitems set
1179 biblioitemnumber = ?, biblionumber = ?,
1180 volume = ?, number = ?,
1181 classification = ?, itemtype = ?,
1183 issn = ?, dewey = ?,
1184 subclass = ?, publicationyear = ?,
1185 publishercode = ?, volumedate = ?,
1186 volumeddesc = ?, illus = ?,
1187 pages = ?, notes = ?,
1189 marc = ?, place = ?,
1193 $biblioitemnumber, $biblioitem->{'biblionumber'},
1194 $biblioitem->{'volume'}, $biblioitem->{'number'},
1195 $biblioitem->{'classification'}, $biblioitem->{'itemtype'},
1196 $biblioitem->{'url'}, $biblioitem->{'isbn'},
1197 $biblioitem->{'issn'}, $biblioitem->{'dewey'},
1198 $biblioitem->{'subclass'}, $biblioitem->{'publicationyear'},
1199 $biblioitem->{'publishercode'}, $biblioitem->{'volumedate'},
1200 $biblioitem->{'volumeddesc'}, $biblioitem->{'illus'},
1201 $biblioitem->{'pages'}, $biblioitem->{'bnotes'},
1202 $biblioitem->{'size'}, $biblioitem->{'lccn'},
1203 $biblioitem->{'marc'}, $biblioitem->{'place'},
1204 $biblioitem->{marcxml},
1206 $dbh->do("unlock tables");
1207 zebra_create($biblioitem->{biblionumber}, $record);
1208 return ($biblioitemnumber);
1211 =head2 REALnewsubtitle($dbh,$bibnum,$subtitle);
1215 create a new subtitle
1220 sub REALnewsubtitle {
1221 my ( $dbh, $bibnum, $subtitle ) = @_;
1224 "insert into bibliosubtitle set biblionumber = ?, subtitle = ?");
1225 $sth->execute( $bibnum, $subtitle ) if $subtitle;
1229 =head2 ($itemnumber,$errors)= REALnewitems($dbh,$item,$barcode);
1233 create a item. $item is a hash and $barcode the barcode.
1240 my ( $dbh, $item, $barcode ) = @_;
1242 # warn "OLDNEWITEMS";
1244 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE');
1245 my $sth = $dbh->prepare("Select max(itemnumber) from items");
1250 $data = $sth->fetchrow_hashref;
1251 $itemnumber = $data->{'max(itemnumber)'} + 1;
1253 # FIXME the "notforloan" field seems to be named "loan" in some places. workaround bugfix.
1254 if ( $item->{'loan'} ) {
1255 $item->{'notforloan'} = $item->{'loan'};
1258 # if dateaccessioned is provided, use it. Otherwise, set to NOW()
1259 if ( $item->{'dateaccessioned'} ) {
1260 $sth = $dbh->prepare( "Insert into items set
1261 itemnumber = ?, biblionumber = ?,
1262 multivolumepart = ?,
1263 biblioitemnumber = ?, barcode = ?,
1264 booksellerid = ?, dateaccessioned = ?,
1265 homebranch = ?, holdingbranch = ?,
1266 price = ?, replacementprice = ?,
1267 replacementpricedate = NOW(), datelastseen = NOW(),
1268 multivolume = ?, stack = ?,
1269 itemlost = ?, wthdrawn = ?,
1270 paidfor = ?, itemnotes = ?,
1271 itemcallnumber =?, notforloan = ?,
1276 $itemnumber, $item->{'biblionumber'},
1277 $item->{'multivolumepart'},
1278 $item->{'biblioitemnumber'},$barcode,
1279 $item->{'booksellerid'}, $item->{'dateaccessioned'},
1280 $item->{'homebranch'}, $item->{'holdingbranch'},
1281 $item->{'price'}, $item->{'replacementprice'},
1282 $item->{multivolume}, $item->{stack},
1283 $item->{itemlost}, $item->{wthdrawn},
1284 $item->{paidfor}, $item->{'itemnotes'},
1285 $item->{'itemcallnumber'}, $item->{'notforloan'},
1288 if ( defined $sth->errstr ) {
1289 $error .= $sth->errstr;
1293 $sth = $dbh->prepare( "Insert into items set
1294 itemnumber = ?, biblionumber = ?,
1295 multivolumepart = ?,
1296 biblioitemnumber = ?, barcode = ?,
1297 booksellerid = ?, dateaccessioned = NOW(),
1298 homebranch = ?, holdingbranch = ?,
1299 price = ?, replacementprice = ?,
1300 replacementpricedate = NOW(), datelastseen = NOW(),
1301 multivolume = ?, stack = ?,
1302 itemlost = ?, wthdrawn = ?,
1303 paidfor = ?, itemnotes = ?,
1304 itemcallnumber =?, notforloan = ?,
1309 $itemnumber, $item->{'biblionumber'},
1310 $item->{'multivolumepart'},
1311 $item->{'biblioitemnumber'},$barcode,
1312 $item->{'booksellerid'},
1313 $item->{'homebranch'}, $item->{'holdingbranch'},
1314 $item->{'price'}, $item->{'replacementprice'},
1315 $item->{multivolume}, $item->{stack},
1316 $item->{itemlost}, $item->{wthdrawn},
1317 $item->{paidfor}, $item->{'itemnotes'},
1318 $item->{'itemcallnumber'}, $item->{'notforloan'},
1321 if ( defined $sth->errstr ) {
1322 $error .= $sth->errstr;
1325 # item stored, now, deal with the marc part...
1326 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1327 where biblio.biblionumber=biblioitems.biblionumber and
1328 biblio.biblionumber=?");
1329 $sth->execute($item->{biblionumber});
1330 if ( defined $sth->errstr ) {
1331 $error .= $sth->errstr;
1333 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1334 warn "ERROR IN OLDnewitem, MARC record not found FOR $item->{biblionumber} => $rawmarc <=" unless $rawmarc;
1335 my $record = MARC::File::USMARC::decode($rawmarc);
1336 # ok, we have the marc record, add item number to the item field (in {marc}, and add the field to the record)
1337 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1338 my $itemrecord = MARC::File::USMARC::decode($item->{marc});
1339 my $itemfield = $itemrecord->field($itemnumberfield);
1340 $itemfield->add_subfields($itemnumbersubfield => "$itemnumber");
1341 $record->insert_grouped_field($itemfield);
1342 # save the record into biblioitem
1343 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=?");
1344 $sth->execute($record->as_usmarc(),$record->as_xml(),$item->{biblionumber});
1345 if ( defined $sth->errstr ) {
1346 $error .= $sth->errstr;
1348 zebra_create($item->{biblionumber},$record);
1349 $dbh->do('unlock tables');
1350 return ( $itemnumber, $error );
1353 =head2 REALmoditem($dbh,$item);
1364 my ( $dbh, $item ) = @_;
1366 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE');
1367 $item->{'itemnum'} = $item->{'itemnumber'} unless $item->{'itemnum'};
1368 my $query = "update items set barcode=?,itemnotes=?,itemcallnumber=?,notforloan=?,location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1370 $item->{'barcode'}, $item->{'notes'},
1371 $item->{'itemcallnumber'}, $item->{'notforloan'},
1372 $item->{'location'}, $item->{multivolumepart},
1373 $item->{multivolume}, $item->{stack},
1376 if ( $item->{'lost'} ne '' ) {
1377 $query = "update items set biblioitemnumber=?,barcode=?,itemnotes=?,homebranch=?,
1378 itemlost=?,wthdrawn=?,itemcallnumber=?,notforloan=?,
1379 location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1381 $item->{'bibitemnum'}, $item->{'barcode'},
1382 $item->{'notes'}, $item->{'homebranch'},
1383 $item->{'lost'}, $item->{'wthdrawn'},
1384 $item->{'itemcallnumber'}, $item->{'notforloan'},
1385 $item->{'location'}, $item->{multivolumepart},
1386 $item->{multivolume}, $item->{stack},
1389 if ($item->{homebranch}) {
1390 $query.=",homebranch=?";
1391 push @bind, $item->{homebranch};
1393 if ($item->{holdingbranch}) {
1394 $query.=",holdingbranch=?";
1395 push @bind, $item->{holdingbranch};
1398 $query.=" where itemnumber=?";
1399 push @bind,$item->{'itemnum'};
1400 if ( $item->{'replacement'} ne '' ) {
1401 $query =~ s/ where/,replacementprice='$item->{'replacement'}' where/;
1403 my $sth = $dbh->prepare($query);
1404 $sth->execute(@bind);
1406 # item stored, now, deal with the marc part...
1407 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1408 where biblio.biblionumber=biblioitems.biblionumber and
1409 biblio.biblionumber=? and
1410 biblioitems.biblioitemnumber=?");
1411 $sth->execute($item->{biblionumber},$item->{biblioitemnumber});
1412 if ( defined $sth->errstr ) {
1413 $error .= $sth->errstr;
1415 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1416 warn "ERROR IN REALmoditem, MARC record not found" unless $rawmarc;
1417 my $record = MARC::File::USMARC::decode($rawmarc);
1418 # ok, we have the marc record, find the previous item record for this itemnumber and delete it
1419 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1420 # prepare the new item record
1421 my $itemrecord = MARC::File::USMARC::decode($item->{marc});
1422 my $itemfield = $itemrecord->field($itemnumberfield);
1423 $itemfield->add_subfields($itemnumbersubfield => '$itemnumber');
1424 # parse all fields fields from the complete record
1425 foreach ($record->field($itemnumberfield)) {
1426 # when the previous field is found, replace by the new one
1427 if ($_->subfield($itemnumbersubfield) == $item->{itemnum}) {
1428 $_->replace_with($itemfield);
1431 # $record->insert_grouped_field($itemfield);
1432 # save the record into biblioitem
1433 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=? and biblioitemnumber=?");
1434 $sth->execute($record->as_usmarc(),$record->as_xml(),$item->{biblionumber},$item->{biblioitemnumber});
1435 zebra_create($item->biblionumber,$record);
1436 if ( defined $sth->errstr ) {
1437 $error .= $sth->errstr;
1439 $dbh->do('unlock tables');
1444 =head2 REALdelitem($dbh,$itemnum);
1455 my ( $dbh, $itemnum ) = @_;
1457 # my $dbh=C4Connect;
1458 my $sth = $dbh->prepare("select * from items where itemnumber=?");
1459 $sth->execute($itemnum);
1460 my $data = $sth->fetchrow_hashref;
1462 my $query = "Insert into deleteditems set ";
1464 foreach my $temp ( keys %$data ) {
1465 $query .= "$temp = ?,";
1466 push ( @bind, $data->{$temp} );
1471 $sth = $dbh->prepare($query);
1472 $sth->execute(@bind);
1474 $sth = $dbh->prepare("Delete from items where itemnumber=?");
1475 $sth->execute($itemnum);
1481 =head2 REALdelbiblioitem($dbh,$biblioitemnumber);
1485 deletes a biblioitem
1486 NOTE : not standard sub name. Should be REALdelbiblioitem()
1492 sub REALdelbiblioitem {
1493 my ( $dbh, $biblioitemnumber ) = @_;
1495 # my $dbh = C4Connect;
1496 my $sth = $dbh->prepare( "Select * from biblioitems
1497 where biblioitemnumber = ?"
1501 $sth->execute($biblioitemnumber);
1503 if ( $results = $sth->fetchrow_hashref ) {
1507 "Insert into deletedbiblioitems (biblioitemnumber, biblionumber, volume, number, classification, itemtype,
1508 isbn, issn ,dewey ,subclass ,publicationyear ,publishercode ,volumedate ,volumeddesc ,timestamp ,illus ,
1509 pages ,notes ,size ,url ,lccn ) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
1513 $results->{biblioitemnumber}, $results->{biblionumber},
1514 $results->{volume}, $results->{number},
1515 $results->{classification}, $results->{itemtype},
1516 $results->{isbn}, $results->{issn},
1517 $results->{dewey}, $results->{subclass},
1518 $results->{publicationyear}, $results->{publishercode},
1519 $results->{volumedate}, $results->{volumeddesc},
1520 $results->{timestamp}, $results->{illus},
1521 $results->{pages}, $results->{notes},
1522 $results->{size}, $results->{url},
1526 $dbh->prepare("Delete from biblioitems where biblioitemnumber = ?");
1527 $sth2->execute($biblioitemnumber);
1532 # Now delete all the items attached to the biblioitem
1533 $sth = $dbh->prepare("Select * from items where biblioitemnumber = ?");
1534 $sth->execute($biblioitemnumber);
1536 while ( my $data = $sth->fetchrow_hashref ) {
1537 my $query = "Insert into deleteditems set ";
1539 foreach my $temp ( keys %$data ) {
1540 $query .= "$temp = ?,";
1541 push ( @bind, $data->{$temp} );
1544 my $sth2 = $dbh->prepare($query);
1545 $sth2->execute(@bind);
1548 $sth = $dbh->prepare("Delete from items where biblioitemnumber = ?");
1549 $sth->execute($biblioitemnumber);
1553 } # sub deletebiblioitem
1555 =head2 REALdelbiblio($dbh,$biblio);
1566 my ( $dbh, $biblio ) = @_;
1567 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
1568 $sth->execute($biblio);
1569 if ( my $data = $sth->fetchrow_hashref ) {
1571 my $query = "Insert into deletedbiblio set ";
1573 foreach my $temp ( keys %$data ) {
1574 $query .= "$temp = ?,";
1575 push ( @bind, $data->{$temp} );
1578 #replacing the last , by ",?)"
1580 $sth = $dbh->prepare($query);
1581 $sth->execute(@bind);
1583 $sth = $dbh->prepare("Delete from biblio where biblionumber=?");
1584 $sth->execute($biblio);
1590 =head2 $number = itemcount($biblio);
1594 returns the number of items attached to a biblio
1602 my $dbh = C4::Context->dbh;
1605 my $sth = $dbh->prepare("Select count(*) from items where biblionumber=?");
1606 $sth->execute($biblio);
1607 my $data = $sth->fetchrow_hashref;
1609 return ( $data->{'count(*)'} );
1612 =head2 $biblionumber = newbiblio($biblio);
1616 create a biblio. The parameter is a hash
1624 my $dbh = C4::Context->dbh;
1625 my $bibnum = REALnewbiblio( $dbh, $biblio );
1626 # finds new (MARC bibid
1627 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1628 my $record = &MARCkoha2marcBiblio( $dbh, $bibnum );
1629 MARCaddbiblio( $dbh, $record, $bibnum,'' );
1633 =head2 $biblionumber = &modbiblio($biblio);
1637 Update a biblio record.
1639 C<$biblio> is a reference-to-hash whose keys are the fields in the
1640 biblio table in the Koha database. All fields must be present, not
1641 just the ones you wish to change.
1643 C<&modbiblio> updates the record defined by
1644 C<$biblio-E<gt>{biblionumber}> with the values in C<$biblio>.
1646 C<&modbiblio> returns C<$biblio-E<gt>{biblionumber}> whether it was
1655 my $dbh = C4::Context->dbh;
1656 my $biblionumber=REALmodbiblio($dbh,$biblio);
1657 my $record = MARCkoha2marcBiblio($dbh,$biblionumber,$biblionumber);
1658 # finds new (MARC bibid
1659 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$biblionumber);
1660 MARCmodbiblio($dbh,$bibid,$record,"",0);
1661 return($biblionumber);
1664 =head2 &modsubtitle($biblionumber, $subtitle);
1668 Sets the subtitle of a book.
1670 C<$biblionumber> is the biblionumber of the book to modify.
1672 C<$subtitle> is the new subtitle.
1679 my ( $bibnum, $subtitle ) = @_;
1680 my $dbh = C4::Context->dbh;
1681 &REALmodsubtitle( $dbh, $bibnum, $subtitle );
1684 =head2 &modaddauthor($biblionumber, $author);
1688 Replaces all additional authors for the book with biblio number
1689 C<$biblionumber> with C<$author>. If C<$author> is the empty string,
1690 C<&modaddauthor> deletes all additional authors.
1697 my ( $bibnum, @authors ) = @_;
1698 my $dbh = C4::Context->dbh;
1699 &REALmodaddauthor( $dbh, $bibnum, @authors );
1700 } # sub modaddauthor
1702 =head2 $error = &modsubject($biblionumber, $force, @subjects);
1706 $force - a subject to force
1707 $error - Error message, or undef if successful.
1714 my ( $bibnum, $force, @subject ) = @_;
1715 my $dbh = C4::Context->dbh;
1716 my $error = &REALmodsubject( $dbh, $bibnum, $force, @subject );
1718 # When MARC is off, ensures that the MARC biblio table gets updated with new
1719 # subjects, of course, it deletes the biblio in marc, and then recreates.
1720 # This check is to ensure that no MARC data exists to lose.
1721 if (C4::Context->preference("MARC") eq '0'){
1722 my $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibnum);
1723 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1724 &MARCmodbiblio($dbh,$bibid, $MARCRecord);
1730 =head2 modbibitem($biblioitem);
1734 modify a biblioitem. The parameter is a hash
1741 my ($biblioitem) = @_;
1742 my $dbh = C4::Context->dbh;
1743 &REALmodbiblioitem( $dbh, $biblioitem );
1746 =head2 $biblioitemnumber = newbiblioitem($biblioitem)
1750 create a biblioitem, the parameter is a hash
1757 my ($biblioitem) = @_;
1758 my $dbh = C4::Context->dbh;
1759 my $bibitemnum = &REALnewbiblioitem( $dbh, $biblioitem );
1762 MARCkoha2marcBiblio( $dbh, 0, $bibitemnum )
1763 ; # the 0 means "do NOT retrieve biblio, only biblioitem, in the MARC record
1765 &MARCfind_MARCbibid_from_oldbiblionumber( $dbh,
1766 $biblioitem->{biblionumber} );
1767 &MARCaddbiblio( $dbh, $MARCbiblio, $biblioitem->{biblionumber}, '',$bibid );
1768 return ($bibitemnum);
1771 =head2 newsubtitle($biblionumber,$subtitle);
1775 insert a subtitle for $biblionumber biblio
1783 my ( $bibnum, $subtitle ) = @_;
1784 my $dbh = C4::Context->dbh;
1785 &REALnewsubtitle( $dbh, $bibnum, $subtitle );
1788 =head2 $errors = newitems($item, @barcodes);
1792 insert items ($item is a hash)
1800 my ( $item, @barcodes ) = @_;
1801 my $dbh = C4::Context->dbh;
1805 foreach my $barcode (@barcodes) {
1806 ( $itemnumber, $error ) = &REALnewitems( $dbh, $item, uc($barcode) );
1809 &MARCkoha2marcItem( $dbh, $item->{biblionumber}, $itemnumber );
1810 &MARCadditem( $dbh, $MARCitem, $item->{biblionumber} );
1815 =head2 moditem($item);
1819 modify an item ($item is a hash with all item informations)
1828 my $dbh = C4::Context->dbh;
1829 &REALmoditem( $dbh, $item );
1831 &MARCkoha2marcItem( $dbh, $item->{'biblionumber'}, $item->{'itemnum'} );
1833 &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $item->{biblionumber} );
1834 &MARCmoditem( $dbh, $MARCitem, $bibid, $item->{itemnum}, 0 );
1837 =head2 $error = checkitems($count,@barcodes);
1841 check for each @barcode entry that the barcode is not a duplicate
1848 my ( $count, @barcodes ) = @_;
1849 my $dbh = C4::Context->dbh;
1851 my $sth = $dbh->prepare("Select * from items where barcode=?");
1852 for ( my $i = 0 ; $i < $count ; $i++ ) {
1853 $barcodes[$i] = uc $barcodes[$i];
1854 $sth->execute( $barcodes[$i] );
1855 if ( my $data = $sth->fetchrow_hashref ) {
1856 $error .= " Duplicate Barcode: $barcodes[$i]";
1863 =head2 $delitem($itemnum);
1867 delete item $itemnum being the item number to delete
1875 my $dbh = C4::Context->dbh;
1876 &REALdelitem( $dbh, $itemnum );
1879 =head2 deletebiblioitem($biblioitemnumber);
1883 delete the biblioitem $biblioitemnumber
1889 sub deletebiblioitem {
1890 my ($biblioitemnumber) = @_;
1891 my $dbh = C4::Context->dbh;
1892 &REALdelbiblioitem( $dbh, $biblioitemnumber );
1893 } # sub deletebiblioitem
1895 =head2 delbiblio($biblionumber)
1899 delete biblio $biblionumber
1907 my $dbh = C4::Context->dbh;
1908 &REALdelbiblio( $dbh, $biblio );
1909 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $biblio );
1910 &MARCdelbiblio( $dbh, $bibid, 0 );
1913 =head2 ($count,@results) = getbiblio($biblionumber);
1917 return an array with hash of biblios.
1919 FIXME : biblionumber being the primary key, this sub will always return only 1 result, API should be modified...
1926 my ($biblionumber) = @_;
1927 my $dbh = C4::Context->dbh;
1928 my $sth = $dbh->prepare("Select * from biblio where biblionumber = ?");
1930 # || die "Cannot prepare $query\n" . $dbh->errstr;
1934 $sth->execute($biblionumber);
1936 # || die "Cannot execute $query\n" . $sth->errstr;
1937 while ( my $data = $sth->fetchrow_hashref ) {
1938 $results[$count] = $data;
1943 return ( $count, @results );
1946 =head2 ($count,@results) = getbiblioitem($biblioitemnumber);
1950 return an array with hash of biblioitemss.
1952 FIXME : biblioitemnumber being unique, this sub will always return only 1 result, API should be modified...
1959 my ($biblioitemnum) = @_;
1960 my $dbh = C4::Context->dbh;
1961 my $sth = $dbh->prepare( "Select * from biblioitems where
1962 biblioitemnumber = ?"
1967 $sth->execute($biblioitemnum);
1969 while ( my $data = $sth->fetchrow_hashref ) {
1970 $results[$count] = $data;
1975 return ( $count, @results );
1976 } # sub getbiblioitem
1978 =head2 ($count,@results) = getbiblioitembybiblionumber($biblionumber);
1982 return an array with hash of biblioitems for the given biblionumber.
1988 sub getbiblioitembybiblionumber {
1989 my ($biblionumber) = @_;
1990 my $dbh = C4::Context->dbh;
1991 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?");
1995 $sth->execute($biblionumber);
1997 while ( my $data = $sth->fetchrow_hashref ) {
1998 $results[$count] = $data;
2003 return ( $count, @results );
2006 =head2 ($count,@results) = getitemsbybiblioitem($biblionumber);
2010 returns an array with hash of items
2016 sub getitemsbybiblioitem {
2017 my ($biblioitemnum) = @_;
2018 my $dbh = C4::Context->dbh;
2019 my $sth = $dbh->prepare( "Select * from items, biblio where
2020 biblio.biblionumber = items.biblionumber and biblioitemnumber
2024 # || die "Cannot prepare $query\n" . $dbh->errstr;
2028 $sth->execute($biblioitemnum);
2030 # || die "Cannot execute $query\n" . $sth->errstr;
2031 while ( my $data = $sth->fetchrow_hashref ) {
2032 $results[$count] = $data;
2037 return ( $count, @results );
2038 } # sub getitemsbybiblioitem
2042 # converts ISO 5426 coded string to ISO 8859-1
2043 # sloppy code : should be improved in next issue
2044 my ( $string, $encoding ) = @_;
2047 # $encoding = C4::Context->preference("marcflavour") unless $encoding;
2048 if ( $encoding eq "UNIMARC" ) {
2117 # this handles non-sorting blocks (if implementation requires this)
2118 $string = nsb_clean($_);
2120 elsif ( $encoding eq "USMARC" || $encoding eq "MARC21" ) {
2121 if (/[\xc1-\xff]/) {
2174 # this handles non-sorting blocks (if implementation requires this)
2175 $string = nsb_clean($_);
2182 my $NSB = '\x88'; # NSB : begin Non Sorting Block
2183 my $NSE = '\x89'; # NSE : Non Sorting Block end
2184 # handles non sorting blocks
2188 s/[ ]{0,1}$NSE/) /gm;
2195 my $dbh = C4::Context->dbh;
2196 my $result = MARCmarc2koha($dbh,$record,'');
2198 my ($biblionumber,$bibid,$title);
2199 # search duplicate on ISBN, easy and fast...
2200 if ($result->{isbn}) {
2201 $sth = $dbh->prepare("select biblio.biblionumber,bibid,title from biblio,biblioitems,marc_biblio where biblio.biblionumber=biblioitems.biblionumber and marc_biblio.biblionumber=biblioitems.biblionumber and isbn=?");
2202 $sth->execute($result->{'isbn'});
2203 ($biblionumber,$bibid,$title) = $sth->fetchrow;
2204 return $biblionumber,$bibid,$title if ($biblionumber);
2206 # a more complex search : build a request for SearchMarc::catalogsearch()
2207 my (@tags, @and_or, @excluding, @operator, @value, $offset,$length);
2208 # search on biblio.title
2209 my ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.title","");
2210 if ($record->field($tag)) {
2211 if ($record->field($tag)->subfields($subfield)) {
2212 push @tags, "'".$tag.$subfield."'";
2213 push @and_or, "and";
2214 push @excluding, "";
2215 push @operator, "contains";
2216 push @value, $record->field($tag)->subfield($subfield);
2217 # warn "for title, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2220 # ... and on biblio.author
2221 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.author","");
2222 if ($record->field($tag)) {
2223 if ($record->field($tag)->subfields($subfield)) {
2224 push @tags, "'".$tag.$subfield."'";
2225 push @and_or, "and";
2226 push @excluding, "";
2227 push @operator, "contains";
2228 push @value, $record->field($tag)->subfield($subfield);
2229 # warn "for author, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2232 # ... and on publicationyear.
2233 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publicationyear","");
2234 if ($record->field($tag)) {
2235 if ($record->field($tag)->subfields($subfield)) {
2236 push @tags, "'".$tag.$subfield."'";
2237 push @and_or, "and";
2238 push @excluding, "";
2239 push @operator, "=";
2240 push @value, $record->field($tag)->subfield($subfield);
2241 # warn "for publicationyear, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2245 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.size","");
2246 if ($record->field($tag)) {
2247 if ($record->field($tag)->subfields($subfield)) {
2248 push @tags, "'".$tag.$subfield."'";
2249 push @and_or, "and";
2250 push @excluding, "";
2251 push @operator, "=";
2252 push @value, $record->field($tag)->subfield($subfield);
2253 # warn "for size, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2256 # ... and on publisher.
2257 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publishercode","");
2258 if ($record->field($tag)) {
2259 if ($record->field($tag)->subfields($subfield)) {
2260 push @tags, "'".$tag.$subfield."'";
2261 push @and_or, "and";
2262 push @excluding, "";
2263 push @operator, "=";
2264 push @value, $record->field($tag)->subfield($subfield);
2265 # warn "for publishercode, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2268 # ... and on volume.
2269 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.volume","");
2270 if ($record->field($tag)) {
2271 if ($record->field($tag)->subfields($subfield)) {
2272 push @tags, "'".$tag.$subfield."'";
2273 push @and_or, "and";
2274 push @excluding, "";
2275 push @operator, "=";
2276 push @value, $record->field($tag)->subfield($subfield);
2277 # warn "for volume, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2281 my ($finalresult,$nbresult) = C4::SearchMarc::catalogsearch($dbh,\@tags,\@and_or,\@excluding,\@operator,\@value,0,10);
2282 # there is at least 1 result => return the 1st one
2284 # warn "$nbresult => ".@$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2285 return @$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2287 # no result, returns nothing
2294 if(substr($isbn, 0, 1) <=7) {
2295 $seg1 = substr($isbn, 0, 1);
2296 } elsif(substr($isbn, 0, 2) <= 94) {
2297 $seg1 = substr($isbn, 0, 2);
2298 } elsif(substr($isbn, 0, 3) <= 995) {
2299 $seg1 = substr($isbn, 0, 3);
2300 } elsif(substr($isbn, 0, 4) <= 9989) {
2301 $seg1 = substr($isbn, 0, 4);
2303 $seg1 = substr($isbn, 0, 5);
2305 my $x = substr($isbn, length($seg1));
2307 if(substr($x, 0, 2) <= 19) {
2308 # if(sTmp2 < 10) sTmp2 = "0" sTmp2;
2309 $seg2 = substr($x, 0, 2);
2310 } elsif(substr($x, 0, 3) <= 699) {
2311 $seg2 = substr($x, 0, 3);
2312 } elsif(substr($x, 0, 4) <= 8399) {
2313 $seg2 = substr($x, 0, 4);
2314 } elsif(substr($x, 0, 5) <= 89999) {
2315 $seg2 = substr($x, 0, 5);
2316 } elsif(substr($x, 0, 6) <= 9499999) {
2317 $seg2 = substr($x, 0, 6);
2319 $seg2 = substr($x, 0, 7);
2321 my $seg3=substr($x,length($seg2));
2322 $seg3=substr($seg3,0,length($seg3)-1) ;
2323 my $seg4 = substr($x, -1, 1);
2324 return "$seg1-$seg2-$seg3-$seg4";
2328 END { } # module clean-up code here (global destructor)
2334 Koha Developement team <info@koha.org>
2336 Paul POULAIN paul.poulain@free.fr
2342 # Revision 1.129 2005/08/12 13:50:31 tipaul
2343 # removing useless sub declarations
2345 # Revision 1.128 2005/08/11 16:12:47 tipaul
2346 # Playing with the zebra...
2348 # * go to koha cvs home directory
2349 # * in misc/zebra there is a unimarc directory. I suggest that marc21 libraries create a marc21 directory
2350 # * put your zebra.cfg files here & create your database.
2351 # * from koha cvs home directory, ln -s misc/zebra/marc21 zebra (I mean create a symbolic link to YOUR zebra directory)
2352 # * now, everytime you add/modify a biblio/item your zebra DB is updated correctly.
2355 # * this uses a system call in perl. CPU consumming, but we are waiting for indexdata Perl/zoom
2356 # * deletion still not work
2357 # * UNIMARC zebra config files are provided in misc/zebra/unimarc directory. The most important line being :
2359 # recordId: (bib1,Local-number)
2363 # elm 090 Local-number -
2364 # elm 090/? Local-number -
2365 # elm 090/?/9 Local-number !:w
2367 # (090$9 being the field mapped to biblio.biblionumber in Koha)
2369 # Revision 1.127 2005/08/11 14:37:32 tipaul
2371 # * removing useless subs
2372 # * removing some subs that are also elsewhere
2373 # * renaming all OLDxxx subs to REALxxx subs (should not change anything, as OLDxxx, as well as REAL, are supposed to be for Biblio.pm internal use only)
2375 # Revision 1.126 2005/08/11 09:13:28 tipaul
2376 # just removing useless subs (a lot !!!) for code cleaning
2378 # Revision 1.125 2005/08/11 09:00:07 tipaul
2379 # Ok guys, this time, it seems that item add and modif begin working as expected...
2380 # Still a lot of bugs to fix, of course
2382 # Revision 1.124 2005/08/10 10:21:15 tipaul
2383 # continuing the road to zebra :
2384 # - the biblio add begins to work.
2385 # - the biblio modif begins to work.
2387 # (still without doing anything on zebra)
2388 # (no new change in updatedatabase)
2390 # Revision 1.123 2005/08/09 14:10:28 tipaul
2391 # 1st commit to go to zebra.
2392 # don't update your cvs if you want to have a working head...
2394 # this commit contains :
2395 # * updater/updatedatabase : get rid with marc_* tables, but DON'T remove them. As a lot of things uses them, it would not be a good idea for instance to drop them. If you really want to play, you can rename them to test head without them but being still able to reintroduce them...
2396 # * Biblio.pm : modify MARCgetbiblio to find the raw marc record in biblioitems.marc field, not from marc_subfield_table, modify MARCfindframeworkcode to find frameworkcode in biblio.frameworkcode, modify some other subs to use biblio.biblionumber & get rid of bibid.
2397 # * other files : get rid of bibid and use biblionumber instead.
2400 # * does not do anything on zebra yet.
2401 # * if you rename marc_subfield_table, you can't search anymore.
2402 # * you can view a biblio & bibliodetails, go to MARC editor, but NOT save any modif.
2403 # * don't try to add a biblio, it would add data poorly... (don't try to delete either, it may work, but that would be a surprise ;-) )
2405 # IMPORTANT NOTE : you need MARC::XML package (http://search.cpan.org/~esummers/MARC-XML-0.7/lib/MARC/File/XML.pm), that requires a recent version of MARC::Record
2406 # Updatedatabase stores the iso2709 data in biblioitems.marc field & an xml version in biblioitems.marcxml Not sure we will keep it when releasing the stable version, but I think it's a good idea to have something readable in sql, at least for development stage.
2408 # tipaul cutted previous commit notes