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
27 use MARC::File::USMARC;
32 use vars qw($VERSION @ISA @EXPORT);
34 # set the version for version checking
35 $VERSION = do { my @v = '$Revision$' =~ /\d+/g;
36 shift(@v) . "." . join("_", map {sprintf "%03d", $_ } @v); };
41 # don't forget MARCxxx subs are exported only for testing purposes. Should not be used
42 # as the old-style API and the NEW one are the only public functions.
45 &newbiblio &newbiblioitem
46 &newsubject &newsubtitle &newitems
48 &modbiblio &checkitems &modbibitem
49 &modsubtitle &modsubject &modaddauthor &moditem
51 &delitem &deletebiblioitem &delbiblio
53 &getbiblio &bibdata &bibitems &bibitemdata
54 &barcodes &ItemInfo &itemdata &itemissues &itemcount
55 &getsubject &getaddauthor &getsubtitle
56 &getwebbiblioitems &getwebsites
57 &getbiblioitembybiblionumber
58 &getbiblioitem &getitemsbybiblioitem
60 &MARCfind_marc_from_kohafield
61 &MARCfind_frameworkcode
62 &find_biblioitemnumber
65 &NEWnewbiblio &NEWnewitem
66 &NEWmodbiblio &NEWmoditem
67 &NEWdelbiblio &NEWdelitem
68 &NEWmodbiblioframework
70 &MARCkoha2marcBiblio &MARCmarc2koha
71 &MARCkoha2marcItem &MARChtml2marc &MARChtml2xml
72 &MARCgetbiblio &MARCgetitem
79 &z3950_extended_services
82 &get_item_from_barcode
83 &MARCfind_MARCbibid_from_oldbiblionumber
89 C4::Biblio - Acquisitions, Catalog Management Functions
93 ( lot of changes for Koha 3.X)
95 Koha 1.2 and previous versions used a specific API to manage biblios. This API uses old-DB style parameters.
96 They are based on a hash, and store data in biblio/biblioitems/items tables (plus additionalauthors,
97 bibliosubject and bibliosubtitle where applicable).
99 In Koha 2.X, we introduced a MARC-DB.
101 In Koha 3.X, we removed this MARC-DB for search as we wanted to use Zebra as search system.
103 So in Koha 3.X, saving a record means :
105 - storing the raw marc record (iso2709) in biblioitems.marc field. It contains both biblio & items information.
106 - storing the "decoded information" in biblio/biblioitems/items as previously.
107 - using zebra to manage search & indexing on the MARC data.
109 In Koha, there is a systempreference for "MARC=ON" or "MARC=OFF" :
111 * MARC=ON : when MARC=ON, Koha uses a MARC::Record object (in sub parameters). Saving information in the DB means :
113 - transform the MARC record into a hash
114 - add the raw MARC record into the hash
115 - store them & update Zebra
117 * MARC=OFF : when MARC=OFF, Koha uses a hash object (in sub parameters). Saving information in the DB means :
119 - transform the hash into a MARC record
120 - add the raw marc record into the hash
121 - store them & update zebra
123 That's why we need 3 types of subs :
127 all I<subs beginning by REAL> do the 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).
129 =head2 NEWxxx related subs
133 all I<subs beginning by NEW> use MARC::Record as parameters. It's the API that MUST be used in the MARC acquisition system. They just create the hash, add it the raw marc record. Then, they call REALxxx sub.
135 all subs requires/use $dbh as 1st parameter and a MARC::Record object as 2nd parameter. They sometimes require another parameter.
139 =head2 something_elsexxx related subs
143 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 call REAL subs.
145 all subs require/use $dbh as 1st parameter and a hash as 2nd parameter.
151 =head2 z3950_extended_services
153 z3950_extended_services($serviceType,$serviceOptions,$record);
155 z3950_extended_services is used to handle all interactions with Zebra's extended serices package.
157 C<$serviceType> one of: itemorder,create,drop,commit,update,xmlupdate
159 C<$serviceOptions> a has of key/value pairs. For instance, if service_type is 'update', $service_options should contain:
161 action => update action, one of specialUpdate, recordInsert, recordReplace, recordDelete, elementUpdate.
165 recordidOpaque => Opaque Record ID (user supplied) or recordidNumber => Record ID number (system number).
166 syntax => the record syntax (transfer syntax)
167 databaseName = Database from connection object
169 To set serviceOptions, call set_service_options($serviceType)
171 C<$record> the record, if one is needed for the service type
173 A record should be in XML. You can convert it to XML from MARC by running it through marc2xml().
176 sub z3950_extended_services {
177 my ($serviceType,$serviceOptions,$record) = @_;
179 my $Zconn = C4::Context->Zconn;
180 # create a new package object
181 my $Zpackage = $Zconn->package();
184 $Zpackage->option(action => $serviceOptions->{'action'});
186 if ($serviceOptions->{'databaseName'}) {
187 $Zpackage->option(databaseName => $serviceOptions->{'databaseName'});
189 if ($serviceOptions->{'recordIdNumber'}) {
190 $Zpackage->option(recordIdNumber => $serviceOptions->{'recordIdNumber'});
192 if ($serviceOptions->{'recordIdOpaque'}) {
193 $Zpackage->option(recordIdOpaque => $serviceOptions->{'recordIdOpaque'});
196 # this is an ILL request (Zebra doesn't support it)
197 #if ($serviceType eq 'itemorder') {
198 # $Zpackage->option('contact-name' => $serviceOptions->{'contact-name'});
199 # $Zpackage->option('contact-phone' => $serviceOptions->{'contact-phone'});
200 # $Zpackage->option('contact-email' => $serviceOptions->{'contact-email'});
201 # $Zpackage->option('itemorder-item' => $serviceOptions->{'itemorder-item'});
205 my $xmlrecord = marc2xml($record);
206 $Zpackage->option(record => $xmlrecord);
207 if ($serviceOptions->{'syntax'}) {
208 $Zpackage->option(syntax => $serviceOptions->{'syntax'});
212 # send the request, handle any exception encountered
213 eval { $Zpackage->send($serviceType) };
214 if ($@ && $@->isa("ZOOM::Exception")) {
215 print "Oops! ", $@->message(), "\n";
218 # free up package resources
219 $Zpackage->destroy();
222 =head2 set_service_options
224 my $serviceOptions = set_service_options($serviceType);
226 C<$serviceType> itemorder,create,drop,commit,update,xmlupdate
228 Currently, we only support 'create', 'commit', and 'update'. 'drop' support will be added as soon as Zebra supports it.
232 sub set_service_options {
233 my ($serviceType,$action,$recordId) = @_;
236 if ($serviceType eq 'update') {
238 $serviceOptions->{ 'action' } = $action;
240 $serviceOptions->{ 'action' } = 'specialUpdate';
243 $serviceOptions->{'recordIdNumber'} = $recordId;
246 # FIXME: This needs to be an OID ... if we ever need 'syntax' this sub will need to change
247 # $serviceOptions->{ 'syntax' } = ''; #zebra doesn't support syntaxes other than xml
250 if ($serviceType eq 'commit') {
254 if ($serviceType eq 'create') {
257 if ($serviceType eq 'drop') {
258 die "ERROR: 'drop' not currently supported (by Zebra)";
262 return $serviceOptions;
267 my $xmlrecord = marc2xml($record);
269 Convert from MARC to XML. Note that MARC::File::XML will automatically encode from MARC-8 to UTF-8 as of version .8
271 C<$record> a MARC record
278 eval { $xmlrecord=$record->as_xml_record() };
279 #TODO: better error handling here
281 warn "ERROR: I suspect a badly formatted MARC record";
286 =head2 MARCgettagslib
288 @tagslib = &MARCgettagslib($dbh,1|0,$frameworkcode);
292 2nd param is 1 for liblibrarian and 0 for libopac
293 $frameworkcode contains the framework reference. If empty or does not exist, the default one is used
295 returns a hash with all values for all fields and subfields for a given MARC framework :
296 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
298 ->{mandatory} = $mandatory;
299 ->{repeatable} = $repeatable;
300 ->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
302 ->{mandatory} = $mandatory;
303 ->{repeatable} = $repeatable;
304 ->{authorised_value} = $authorised_value;
305 ->{authtypecode} = $authtypecode;
306 ->{value_builder} = $value_builder;
307 ->{kohafield} = $kohafield;
308 ->{seealso} = $seealso;
309 ->{hidden} = $hidden;
318 # old subroutine to provide backwards compatibility.
319 # opac-detail breaks without this. Can be removed once opac-detail is fixed
320 sub MARCfind_MARCbibid_from_oldbiblionumber {
321 my ($biblionumber)=@_;
322 return ($biblionumber);
327 my ( $dbh, $forlibrarian, $frameworkcode ) = @_;
328 $frameworkcode = "" unless $frameworkcode;
329 $forlibrarian = 1 unless $forlibrarian;
331 my $libfield = ( $forlibrarian eq 1 ) ? 'liblibrarian' : 'libopac';
333 # check that framework exists
336 "select count(*) from marc_tag_structure where frameworkcode=?");
337 $sth->execute($frameworkcode);
338 my ($total) = $sth->fetchrow;
339 $frameworkcode = "" unless ( $total > 0 );
342 "select tagfield,liblibrarian,libopac,mandatory,repeatable from marc_tag_structure where frameworkcode=? order by tagfield"
344 $sth->execute($frameworkcode);
345 my ( $liblibrarian, $libopac, $tag, $res, $tab, $mandatory, $repeatable );
347 while ( ( $tag, $liblibrarian, $libopac, $mandatory, $repeatable ) = $sth->fetchrow ) {
348 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
349 $res->{$tag}->{tab} = ""; # XXX
350 $res->{$tag}->{mandatory} = $mandatory;
351 $res->{$tag}->{repeatable} = $repeatable;
356 "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"
358 $sth->execute($frameworkcode);
361 my $authorised_value;
371 ( $tag, $subfield, $liblibrarian, , $libopac, $tab,
372 $mandatory, $repeatable, $authorised_value, $authtypecode,
373 $value_builder, $kohafield, $seealso, $hidden,
378 $res->{$tag}->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
379 $res->{$tag}->{$subfield}->{tab} = $tab;
380 $res->{$tag}->{$subfield}->{mandatory} = $mandatory;
381 $res->{$tag}->{$subfield}->{repeatable} = $repeatable;
382 $res->{$tag}->{$subfield}->{authorised_value} = $authorised_value;
383 $res->{$tag}->{$subfield}->{authtypecode} = $authtypecode;
384 $res->{$tag}->{$subfield}->{value_builder} = $value_builder;
385 $res->{$tag}->{$subfield}->{kohafield} = $kohafield;
386 $res->{$tag}->{$subfield}->{seealso} = $seealso;
387 $res->{$tag}->{$subfield}->{hidden} = $hidden;
388 $res->{$tag}->{$subfield}->{isurl} = $isurl;
389 $res->{$tag}->{$subfield}->{link} = $link;
394 =head2 MARCfind_marc_from_kohafield
396 ($tagfield,$tagsubfield) = &MARCfind_marc_from_kohafield($dbh,$kohafield);
400 finds MARC tag and subfield for a given kohafield
401 kohafield is "table.field" where table= biblio|biblioitems|items, and field a field of the previous table
407 sub MARCfind_marc_from_kohafield {
408 my ( $dbh, $kohafield,$frameworkcode ) = @_;
409 return 0, 0 unless $kohafield;
410 $frameworkcode='' unless $frameworkcode;
411 my $relations = C4::Context->marcfromkohafield;
412 return ($relations->{$frameworkcode}->{$kohafield}->[0],$relations->{$frameworkcode}->{$kohafield}->[1]);
417 $MARCRecord = &MARCgetbiblio($dbh,$biblionumber);
421 Returns a MARC::Record for the biblio $biblionumber.
427 # Returns MARC::Record of the biblio passed in parameter.
428 my ( $dbh, $biblionumber ) = @_;
429 my $sth = $dbh->prepare('select marc from biblioitems where biblionumber=?');
430 $sth->execute($biblionumber);
431 my ($marc) = $sth->fetchrow;
432 my $record = MARC::Record::new_from_usmarc($marc);
438 $XML = &XMLgetbiblio($dbh,$biblionumber);
442 Returns a raw XML for the biblio $biblionumber.
448 # Returns MARC::Record of the biblio passed in parameter.
449 my ( $dbh, $biblionumber ) = @_;
450 my $sth = $dbh->prepare('select marcxml,marc from biblioitems where biblionumber=?');
451 $sth->execute($biblionumber);
452 my ($XML,$marc) = $sth->fetchrow;
453 # my $record =MARC::Record::new_from_usmarc($marc);
454 # warn "MARC : \n*-************************\n".$record->as_xml."\n*-************************\n";
460 $MARCrecord = &MARCgetitem($dbh,$biblionumber);
464 Returns a MARC::Record with all items of biblio # $biblionumber
472 my ( $dbh, $biblionumber, $itemnumber ) = @_;
473 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
474 # get the complete MARC record
475 my $sth = $dbh->prepare("select marc from biblioitems where biblionumber=?");
476 $sth->execute($biblionumber);
477 my ($rawmarc) = $sth->fetchrow;
478 my $record = C4::Search::get_record($biblionumber);
479 # warn "ITEMRECORD".$record->as_formatted;
480 # now, find the relevant itemnumber
481 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
482 # prepare the new item record
483 my $itemrecord = MARC::Record->new();
484 # parse all fields fields from the complete record
485 foreach ($record->field($itemnumberfield)) {
486 # when the item field is found, save it
487 # warn "Itenumberfield = $itemnumberfield";
488 if ($_->subfield($itemnumbersubfield) == $itemnumber) {
489 # warn "Inside if subfield=$itemnumbersubfield";
490 $itemrecord->append_fields($_);
492 warn "No match subfield=$itemnumbersubfield and
493 itemnumber=$itemnumber";
496 # warn "ITEMS".$itemrecord->as_formatted;
501 ##Changes only field or subfield from the holdings fields of MARC record used for branch transfers or onloan flag -TG
504 sub MARCmoditemonefield{
505 my ($dbh,$biblionumber,$itemnumber,$itemfield,$newvalue)=@_;
507 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
508 # get the complete MARC record
509 my $sth = $dbh->prepare("select marc from biblioitems where biblionumber=?");
510 $sth->execute($biblionumber);
511 my ($rawmarc) = $sth->fetchrow;
512 my $bibliorecord=MARC::File::USMARC::decode($rawmarc);
513 # now, find the relevant itemnumber
514 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
515 my ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,$itemfield,$frameworkcode);
517 # parse all fields fields from the complete record
518 foreach ($bibliorecord->field($itemnumberfield)) {
519 # when the item field is found, update it
520 if ($_->subfield($itemnumbersubfield) == $itemnumber) {
521 $_->update($tagsubfield =>$newvalue);
525 # save the record into biblioitem
526 $dbh->do('lock tables biblioitems WRITE');
527 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=?");
528 $sth->execute($bibliorecord->as_usmarc(),$bibliorecord->as_xml_record(),$biblionumber);
529 z3950_extended_services('update',set_service_options('update'),$bibliorecord);
530 z3950_extended_services('commit');
531 $dbh->do('unlock tables');
534 =head2 find_biblioitemnumber
536 my $biblioitemnumber = find_biblioitemnumber($dbh,$biblionumber);
540 Returns the 1st biblioitemnumber related to $biblionumber. When MARC=ON we should have 1 biblionumber = 1 and only 1 biblioitemnumber
541 This sub is useless when MARC=OFF
546 sub find_biblioitemnumber {
547 my ( $dbh, $biblionumber ) = @_;
548 my $sth = $dbh->prepare("select biblioitemnumber from biblioitems where biblionumber=?");
549 $sth->execute($biblionumber);
550 my ($biblioitemnumber) = $sth->fetchrow;
551 return $biblioitemnumber;
554 =head2 MARCfind_frameworkcode
556 my $frameworkcode = MARCfind_frameworkcode($dbh,$biblionumber);
560 returns the framework of a given biblio
566 sub MARCfind_frameworkcode {
567 my ( $dbh, $biblionumber ) = @_;
568 my $sth = $dbh->prepare("select frameworkcode from biblio where biblionumber=?");
569 $sth->execute($biblionumber);
570 my ($frameworkcode) = $sth->fetchrow;
571 return $frameworkcode;
574 =head2 MARCkoha2marcBiblio
576 $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibliohash);
580 MARCkoha2marcBiblio is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB biblio/biblioitem :
581 all entries of the hash are transformed into their matching MARC field/subfield.
587 sub MARCkoha2marcBiblio {
589 # this function builds partial MARC::Record from the old koha-DB fields
590 my ( $dbh, $bibliohash ) = @_;
591 # we don't have biblio entries in the hash, so we add them first
592 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
593 $sth->execute($bibliohash->{biblionumber});
594 my $biblio = $sth->fetchrow_hashref;
595 foreach (keys %$biblio) {
596 $bibliohash->{$_}=$biblio->{$_};
598 $sth = $dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
599 my $record = MARC::Record->new();
600 foreach ( keys %$bibliohash ) {
601 &MARCkoha2marcOnefield( $sth, $record, "biblio." . $_, $bibliohash->{$_}, '') if $bibliohash->{$_};
602 &MARCkoha2marcOnefield( $sth, $record, "biblioitems." . $_, $bibliohash->{$_}, '') if $bibliohash->{$_};
605 # other fields => additional authors, subjects, subtitles
606 my $sth2 = $dbh->prepare(" SELECT author FROM additionalauthors WHERE biblionumber=?");
607 $sth2->execute($bibliohash->{biblionumber});
608 while ( my $row = $sth2->fetchrow_hashref ) {
609 &MARCkoha2marcOnefield( $sth, $record, "additionalauthors.author", $bibliohash->{'author'},'' );
611 $sth2 = $dbh->prepare(" SELECT subject FROM bibliosubject WHERE biblionumber=?");
612 $sth2->execute($bibliohash->{biblionumber});
613 while ( my $row = $sth2->fetchrow_hashref ) {
614 &MARCkoha2marcOnefield( $sth, $record, "bibliosubject.subject", $row->{'subject'},'' );
616 $sth2 = $dbh->prepare(" SELECT subtitle FROM bibliosubtitle WHERE biblionumber=?");
617 $sth2->execute($bibliohash->{biblionumber});
618 while ( my $row = $sth2->fetchrow_hashref ) {
619 &MARCkoha2marcOnefield( $sth, $record, "bibliosubtitle.subtitle", $row->{'subtitle'},'' );
625 =head2 MARCkoha2marcItem
627 $MARCRecord = &MARCkoha2marcItem($dbh,$biblionumber,itemnumber);
629 MARCkoha2marcItem is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB items :
630 all entries of the hash are transformed into their matching MARC field/subfield.
638 sub MARCkoha2marcItem {
640 # this function builds partial MARC::Record from the old koha-DB fields
641 my ( $dbh, $item ) = @_;
643 # my $dbh=&C4Connect;
644 my $sth = $dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
645 my $record = MARC::Record->new();
647 foreach( keys %$item ) {
649 &MARCkoha2marcOnefield( $sth, $record, "items." . $_,
656 =head2 MARCkoha2marcOnefield
660 This sub is for internal use only, used by koha2marcBiblio & koha2marcItem
666 sub MARCkoha2marcOnefield {
667 my ( $sth, $record, $kohafieldname, $value,$frameworkcode ) = @_;
670 $sth->execute($frameworkcode,$kohafieldname);
671 if ( ( $tagfield, $tagsubfield ) = $sth->fetchrow ) {
672 if ( $record->field($tagfield) ) {
673 my $tag = $record->field($tagfield);
675 $tag->add_subfields( $tagsubfield, $value );
676 $record->delete_field($tag);
677 $record->add_fields($tag);
681 $record->add_fields( $tagfield, " ", " ", $tagsubfield => $value );
688 $XMLrecord = MARChtml2xml($rtags,$rsubfields,$rvalues,$indicator,$ind_tag);
690 transforms the parameters (coming from HTML form) into a MARC::File::XML
691 object. parameters with r are references to arrays
695 my ($tags,$subfields,$values,$indicator,$ind_tag) = @_;
697 my $xml= MARC::File::XML::header();
702 for (my $i=0;$i<=@$tags;$i++){
703 @$values[$i] =~ s/&/&/g;
704 @$values[$i] =~ s/</</g;
705 @$values[$i] =~ s/>/>/g;
706 @$values[$i] =~ s/"/"/g;
707 @$values[$i] =~ s/'/'/g;
709 if ((@$tags[$i] ne $prevtag)){
710 $j++ unless (@$tags[$i] eq "");
711 #warn "IND:".substr(@$indicator[$j],0,1).substr(@$indicator[$j],1,1)." ".@$tags[$i];
713 $xml.="</datafield>\n";
714 if ((@$tags[$i] > 10) && (@$values[$i] ne "")){
715 my $ind1 = substr(@$indicator[$j],0,1);
716 my $ind2 = substr(@$indicator[$j],1,1);
717 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
718 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
724 if (@$values[$i] ne "") {
726 if (@$tags[$i] eq "000") {
727 $xml.="<leader>@$values[$i]</leader>\n";
729 # rest of the fixed fields
730 } elsif (@$tags[$i] < 10) {
731 $xml.="<controlfield tag=\"@$tags[$i]\">@$values[$i]</controlfield>\n";
734 my $ind1 = substr(@$indicator[$j],0,1);
735 my $ind2 = substr(@$indicator[$j],1,1);
736 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
737 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
742 } else { # @$tags[$i] eq $prevtag
743 if (@$values[$i] eq "") {
747 my $ind1 = substr(@$indicator[$j],0,1);
748 my $ind2 = substr(@$indicator[$j],1,1);
749 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
752 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
755 $prevtag = @$tags[$i];
757 $xml.= MARC::File::XML::footer();
764 $hash = &MARCmarc2koha($dbh,$MARCRecord);
768 builds a hash with old-db datas from a MARC::Record
775 my ($dbh,$record,$frameworkcode) = @_;
776 my $sth=$dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
778 my $sth2=$dbh->prepare("SHOW COLUMNS from biblio");
781 while (($field)=$sth2->fetchrow) {
782 # warn "biblio.".$field;
783 $result=&MARCmarc2kohaOneField($sth,"biblio",$field,$record,$result,$frameworkcode);
785 $sth2=$dbh->prepare("SHOW COLUMNS from biblioitems");
787 while (($field)=$sth2->fetchrow) {
788 if ($field eq 'notes') { $field = 'bnotes'; }
789 # warn "biblioitems".$field;
790 $result=&MARCmarc2kohaOneField($sth,"biblioitems",$field,$record,$result,$frameworkcode);
792 $sth2=$dbh->prepare("SHOW COLUMNS from items");
794 while (($field)=$sth2->fetchrow) {
795 # warn "items".$field;
796 $result=&MARCmarc2kohaOneField($sth,"items",$field,$record,$result,$frameworkcode);
798 # additional authors : specific
799 $result = &MARCmarc2kohaOneField($sth,"bibliosubtitle","subtitle",$record,$result,$frameworkcode);
800 $result = &MARCmarc2kohaOneField($sth,"additionalauthors","additionalauthors",$record,$result,$frameworkcode);
801 # modify copyrightdate to keep only the 1st year found
802 my $temp = $result->{'copyrightdate'};
804 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
806 $result->{'copyrightdate'} = $1;
807 } else { # if no cYYYY, get the 1st date.
808 $temp =~ m/(\d\d\d\d)/;
809 $result->{'copyrightdate'} = $1;
812 # modify publicationyear to keep only the 1st year found
813 $temp = $result->{'publicationyear'};
814 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
816 $result->{'publicationyear'} = $1;
817 } else { # if no cYYYY, get the 1st date.
818 $temp =~ m/(\d\d\d\d)/;
819 $result->{'publicationyear'} = $1;
824 sub MARCmarc2kohaOneField {
826 # FIXME ? if a field has a repeatable subfield that is used in old-db, only the 1st will be retrieved...
827 my ( $sth, $kohatable, $kohafield, $record, $result,$frameworkcode ) = @_;
828 # warn "kohatable / $kohafield / $result / ";
832 ( $tagfield, $subfield ) = MARCfind_marc_from_kohafield("",$kohatable.".".$kohafield,$frameworkcode);
833 foreach my $field ( $record->field($tagfield) ) {
834 if ($field->tag()<10) {
835 if ($result->{$kohafield}) {
836 # Reverse array filled with elements from repeated subfields
837 # from first to last to avoid last to first concatenation of
838 # elements in Koha DB. -- thd.
839 $result->{$kohafield} .= " | ".reverse($field->data());
841 $result->{$kohafield} = $field->data();
844 if ( $field->subfields ) {
845 my @subfields = $field->subfields();
846 foreach my $subfieldcount ( 0 .. $#subfields ) {
847 if ($subfields[$subfieldcount][0] eq $subfield) {
848 if ( $result->{$kohafield} ) {
849 $result->{$kohafield} .= " | " . $subfields[$subfieldcount][1];
852 $result->{$kohafield} = $subfields[$subfieldcount][1];
859 # warn "OneField for $kohatable.$kohafield and $frameworkcode=> $tagfield, $subfield";
865 ($biblionumber,$biblioitemnumber) = NEWnewbibilio($dbh,$MARCRecord,$frameworkcode);
869 creates a biblio from a MARC::Record.
876 my ( $dbh,$record,$frameworkcode ) = @_;
878 my $biblioitemnumber;
879 my $olddata = MARCmarc2koha( $dbh, $record,$frameworkcode );
880 $olddata->{frameworkcode} = $frameworkcode;
881 $biblionumber = REALnewbiblio( $dbh, $olddata );
882 $olddata->{biblionumber} = $biblionumber;
883 # add biblionumber into the MARC record (it's the ID for zebra)
884 my ( $tagfield, $tagsubfield ) =
885 MARCfind_marc_from_kohafield( $dbh, "biblio.biblionumber",$frameworkcode );
889 $newfield = MARC::Field->new(
890 $tagfield, $biblionumber,
893 $newfield = MARC::Field->new(
894 $tagfield, '', '', "$tagsubfield" => $biblionumber,
897 # drop old field (just in case it already exist and create new one...
898 my $old_field = $record->field($tagfield);
899 $record->delete_field($old_field);
900 $record->add_fields($newfield);
901 #Change MARC Leader to UTF-8 incase user did not set it.New M::F::XML is sensitive to this
902 $record->encoding('UTF-8');
903 #create the marc entry, that stores the rax marc record in Koha 3.0
904 $olddata->{marc} = $record->as_usmarc();
905 $olddata->{marcxml} = $record->as_xml_record();
906 # and create biblioitem, that's all folks !
907 $biblioitemnumber = REALnewbiblioitem( $dbh, $olddata );
909 # search subtiles, addiauthors and subjects
910 ( $tagfield, $tagsubfield ) =
911 MARCfind_marc_from_kohafield( $dbh, "additionalauthors.author",$frameworkcode );
912 my @addiauthfields = $record->field($tagfield);
913 foreach my $addiauthfield (@addiauthfields) {
914 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
915 foreach my $subfieldcount ( 0 .. $#addiauthsubfields ) {
916 REALmodaddauthor( $dbh, $biblionumber,
917 $addiauthsubfields[$subfieldcount] );
920 ( $tagfield, $tagsubfield ) =
921 MARCfind_marc_from_kohafield( $dbh, "bibliosubtitle.subtitle",$frameworkcode );
922 my @subtitlefields = $record->field($tagfield);
923 foreach my $subtitlefield (@subtitlefields) {
924 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
925 foreach my $subfieldcount ( 0 .. $#subtitlesubfields ) {
926 REALnewsubtitle( $dbh, $biblionumber,
927 $subtitlesubfields[$subfieldcount] );
930 ( $tagfield, $tagsubfield ) =
931 MARCfind_marc_from_kohafield( $dbh, "bibliosubject.subject",$frameworkcode );
932 my @subj = $record->field($tagfield);
934 foreach my $subject (@subj) {
935 my @subjsubfield = $subject->subfield($tagsubfield);
936 foreach my $subfieldcount ( 0 .. $#subjsubfield ) {
937 push @subjects, $subjsubfield[$subfieldcount];
940 REALmodsubject( $dbh, $biblionumber, 1, @subjects );
941 return ( $biblionumber, $biblioitemnumber );
944 =head2 NEWmodbilbioframework
946 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
950 modify the framework of a biblio
956 sub NEWmodbiblioframework {
957 my ($dbh,$biblionumber,$frameworkcode) =@_;
958 my $sth = $dbh->prepare("Update biblio SET frameworkcode=? WHERE biblionumber=?");
959 $sth->execute($frameworkcode,$biblionumber);
965 NEWmodbiblio($dbh,$MARCrecord,$biblionumber,$frameworkcode);
969 modify a biblio (MARC=ON)
976 my ($dbh,$record,$biblionumber,$frameworkcode) =@_;
977 $frameworkcode="" unless $frameworkcode;
978 # &MARCmodbiblio($dbh,$bibid,$record,$frameworkcode,0);
979 my $oldbiblio = MARCmarc2koha($dbh,$record,$frameworkcode);
981 $oldbiblio->{frameworkcode} = $frameworkcode;
982 #create the marc entry, that stores the rax marc record in Koha 3.0
983 $oldbiblio->{biblionumber} = $biblionumber unless $oldbiblio->{biblionumber};
984 $oldbiblio->{marc} = $record->as_usmarc();
985 $oldbiblio->{marcxml} = $record->as_xml_record();
986 warn "dans NEWmodbiblio $biblionumber = ".$oldbiblio->{biblionumber}." = ".$oldbiblio->{marcxml};
987 REALmodbiblio($dbh,$oldbiblio);
988 REALmodbiblioitem($dbh,$oldbiblio);
989 # now, modify addi authors, subject, addititles.
990 my ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"additionalauthors.author",$frameworkcode);
991 my @addiauthfields = $record->field($tagfield);
992 foreach my $addiauthfield (@addiauthfields) {
993 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
994 $dbh->do("delete from additionalauthors where biblionumber=$biblionumber");
995 foreach my $subfieldcount (0..$#addiauthsubfields) {
996 REALmodaddauthor($dbh,$biblionumber,$addiauthsubfields[$subfieldcount]);
999 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubtitle.subtitle",$frameworkcode);
1000 my @subtitlefields = $record->field($tagfield);
1001 foreach my $subtitlefield (@subtitlefields) {
1002 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
1003 # delete & create subtitle again because REALmodsubtitle can't handle new subtitles
1005 $dbh->do("delete from bibliosubtitle where biblionumber=$biblionumber");
1006 foreach my $subfieldcount (0..$#subtitlesubfields) {
1007 foreach my $subtit(split /\||#/,$subtitlesubfields[$subfieldcount]) {
1008 REALnewsubtitle($dbh,$biblionumber,$subtit);
1012 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubject.subject",$frameworkcode);
1013 my @subj = $record->field($tagfield);
1015 foreach my $subject (@subj) {
1016 my @subjsubfield = $subject->subfield($tagsubfield);
1017 foreach my $subfieldcount (0..$#subjsubfield) {
1018 push @subjects,$subjsubfield[$subfieldcount];
1021 REALmodsubject($dbh,$biblionumber,1,@subjects);
1025 =head2 NEWmodbilbioframework
1027 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
1038 my ( $dbh, $bibid ) = @_;
1039 # my $biblio = &MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
1040 &REALdelbiblio( $dbh, $bibid );
1043 "select biblioitemnumber from biblioitems where biblionumber=?");
1044 $sth->execute($bibid);
1045 while ( my ($biblioitemnumber) = $sth->fetchrow ) {
1046 REALdelbiblioitem( $dbh, $biblioitemnumber );
1048 # &MARCdelbiblio( $dbh, $bibid, 0 );
1050 warn "heres the bibid $bibid";
1051 # my $record = C4::Search::get_record($bibid);
1052 my $record = C4::Search::get_xml_record($bibid);
1053 # z3950_extended_services('update',set_service_options('update'),$record);
1054 warn "heres the record to delete $bibid";
1055 my $Zconn = C4::Context->Zconn;
1056 my $p = $Zconn->package();
1057 $p->option(action => "recordDelete");
1058 $p->option(record => $record);
1061 # z3950_extended_services('update',set_service_options('update','recordDelete',$record));
1062 z3950_extended_services('commit');
1067 $itemnumber = NEWnewitem($dbh, $record, $biblionumber, $biblioitemnumber);
1071 creates an item from a MARC::Record
1078 my ( $dbh,$record,$biblionumber,$biblioitemnumber ) = @_;
1079 warn "here is the $biblioitemnumber";
1080 # add item in old-DB
1081 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
1082 my $item = &MARCmarc2koha( $dbh,$record,$frameworkcode );
1083 # needs old biblionumber and biblioitemnumber
1084 $item->{'biblionumber'} = $biblionumber;
1085 $item->{'biblioitemnumber'}=$biblioitemnumber;
1086 $item->{marc} = $record->as_usmarc();
1087 #warn $item->{marc};
1088 my ( $itemnumber, $error ) = &REALnewitems( $dbh, $item, $item->{barcode} );
1095 $itemnumber = NEWmoditem($dbh, $record, $biblionumber, $biblioitemnumber,$itemnumber);
1106 my ( $dbh, $record, $biblionumber, $biblioitemnumber, $itemnumber) = @_;
1108 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
1109 my $olditem = MARCmarc2koha( $dbh, $record,$frameworkcode );
1111 $olditem->{marc} = $record->as_usmarc();
1112 $olditem->{biblionumber} = $biblionumber;
1113 $olditem->{biblioitemnumber} = $biblioitemnumber;
1115 REALmoditem( $dbh, $olditem );
1121 $itemnumber = NEWdelitem($dbh, $biblionumber, $biblioitemnumber, $itemnumber);
1132 my ( $dbh, $bibid, $itemnumber ) = @_;
1133 &REALdelitem( $dbh, $itemnumber );
1134 # &MARCdelitem( $dbh, $bibid, $itemnumber );
1135 # we must now delete the item data from zebra
1139 =head2 REALnewbiblio
1141 $biblionumber = REALnewbiblio($dbh,$biblio);
1145 adds a record in biblio table. Datas are in the hash $biblio.
1152 my ( $dbh, $biblio ) = @_;
1154 $dbh->do('lock tables biblio WRITE');
1155 my $sth = $dbh->prepare("Select max(biblionumber) from biblio");
1157 my $data = $sth->fetchrow_arrayref;
1158 my $bibnum = $$data[0] + 1;
1161 if ( $biblio->{'seriestitle'} ) { $series = 1 }
1164 $dbh->prepare("insert into biblio set biblionumber=?, title=?, author=?, copyrightdate=?,
1165 serial=?, seriestitle=?, notes=?, abstract=?,
1169 $bibnum, $biblio->{'title'},
1170 $biblio->{'author'}, $biblio->{'copyrightdate'},
1171 $biblio->{'serial'}, $biblio->{'seriestitle'},
1172 $biblio->{'notes'}, $biblio->{'abstract'},
1173 $biblio->{'unititle'}
1177 $dbh->do('unlock tables');
1181 =head2 REALmodbiblio
1183 $biblionumber = REALmodbiblio($dbh,$biblio);
1187 modify a record in biblio table. Datas are in the hash $biblio.
1194 my ( $dbh, $biblio ) = @_;
1195 my $sth = $dbh->prepare("Update biblio set title=?, author=?, abstract=?, copyrightdate=?,
1196 seriestitle=?, serial=?, unititle=?, notes=?, frameworkcode=?
1197 where biblionumber = ?"
1200 $biblio->{'title'}, $biblio->{'author'},
1201 $biblio->{'abstract'}, $biblio->{'copyrightdate'},
1202 $biblio->{'seriestitle'}, $biblio->{'serial'},
1203 $biblio->{'unititle'}, $biblio->{'notes'},
1204 $biblio->{frameworkcode},
1205 $biblio->{'biblionumber'}
1208 return ( $biblio->{'biblionumber'} );
1211 =head2 REALmodsubtitle
1213 REALmodsubtitle($dbh,$bibnum,$subtitle);
1217 modify subtitles in bibliosubtitle table.
1223 sub REALmodsubtitle {
1224 my ( $dbh, $bibnum, $subtitle ) = @_;
1227 "update bibliosubtitle set subtitle = ? where biblionumber = ?");
1228 $sth->execute( $subtitle, $bibnum );
1232 =head2 REALmodaddauthor
1234 REALmodaddauthor($dbh,$bibnum,$author);
1238 adds or modify additional authors
1239 NOTE : Strange sub : seems to delete MANY and add only ONE author... maybe buggy ?
1245 sub REALmodaddauthor {
1246 my ( $dbh, $bibnum, @authors ) = @_;
1248 # my $dbh = C4Connect;
1250 $dbh->prepare("Delete from additionalauthors where biblionumber = ?");
1252 $sth->execute($bibnum);
1254 foreach my $author (@authors) {
1255 if ( $author ne '' ) {
1258 "Insert into additionalauthors set author = ?, biblionumber = ?"
1261 $sth->execute( $author, $bibnum );
1266 } # sub modaddauthor
1268 =head2 REALmodsubject
1270 $errors = REALmodsubject($dbh,$bibnum, $force, @subject);
1274 modify/adds subjects
1279 sub REALmodsubject {
1280 my ( $dbh, $bibnum, $force, @subject ) = @_;
1282 # my $dbh = C4Connect;
1283 my $count = @subject;
1285 for ( my $i = 0 ; $i < $count ; $i++ ) {
1286 $subject[$i] =~ s/^ //g;
1287 $subject[$i] =~ s/ $//g;
1290 "select * from catalogueentry where entrytype = 's' and catalogueentry = ?"
1292 $sth->execute( $subject[$i] );
1294 if ( my $data = $sth->fetchrow_hashref ) {
1297 if ( $force eq $subject[$i] || $force == 1 ) {
1299 # subject not in aut, chosen to force anway
1300 # so insert into cataloguentry so its in auth file
1303 "Insert into catalogueentry (entrytype,catalogueentry) values ('s',?)"
1306 $sth2->execute( $subject[$i] ) if ( $subject[$i] );
1311 "$subject[$i]\n does not exist in the subject authority file";
1314 "Select * from catalogueentry where entrytype = 's' and (catalogueentry like ? or catalogueentry like ? or catalogueentry like ?)"
1316 $sth2->execute( "$subject[$i] %", "% $subject[$i] %",
1318 while ( my $data = $sth2->fetchrow_hashref ) {
1319 $error .= "<br>$data->{'catalogueentry'}";
1328 $dbh->prepare("Delete from bibliosubject where biblionumber = ?");
1329 $sth->execute($bibnum);
1333 "Insert into bibliosubject (subject,biblionumber) values (?,?)");
1335 foreach $query (@subject) {
1336 $sth->execute( $query, $bibnum ) if ( $query && $bibnum );
1345 =head2 REALmodbiblioitem
1347 REALmodbiblioitem($dbh, $biblioitem);
1356 sub REALmodbiblioitem {
1357 my ( $dbh, $biblioitem ) = @_;
1360 my $sth = $dbh->prepare("update biblioitems set number=?,volume=?, volumedate=?, lccn=?,
1361 itemtype=?, url=?, isbn=?, issn=?,
1362 publishercode=?, publicationyear=?, classification=?, dewey=?,
1363 subclass=?, illus=?, pages=?, volumeddesc=?,
1364 notes=?, size=?, place=?, marc=?,
1366 where biblioitemnumber=?");
1367 $sth->execute( $biblioitem->{number}, $biblioitem->{volume}, $biblioitem->{volumedate}, $biblioitem->{lccn},
1368 $biblioitem->{itemtype}, $biblioitem->{url}, $biblioitem->{isbn}, $biblioitem->{issn},
1369 $biblioitem->{publishercode}, $biblioitem->{publicationyear}, $biblioitem->{classification}, $biblioitem->{dewey},
1370 $biblioitem->{subclass}, $biblioitem->{illus}, $biblioitem->{pages}, $biblioitem->{volumeddesc},
1371 $biblioitem->{bnotes}, $biblioitem->{size}, $biblioitem->{place}, $biblioitem->{marc},
1372 $biblioitem->{marcxml}, $biblioitem->{biblioitemnumber});
1374 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1376 z3950_extended_services('update',set_service_options('update'),$record);
1377 z3950_extended_services('commit');
1380 # warn "MOD : $biblioitem->{biblioitemnumber} = ".$biblioitem->{marc};
1383 =head2 REALnewbiblioitem
1385 REALnewbiblioitem($dbh,$biblioitem);
1389 adds a biblioitem ($biblioitem is a hash with the values)
1395 sub REALnewbiblioitem {
1396 my ( $dbh, $biblioitem ) = @_;
1398 $dbh->do("lock tables biblioitems WRITE, biblio WRITE, marc_subfield_structure READ");
1399 my $sth = $dbh->prepare("Select max(biblioitemnumber) from biblioitems");
1401 my $biblioitemnumber;
1404 $data = $sth->fetchrow_arrayref;
1405 $biblioitemnumber = $$data[0] + 1;
1407 # Insert biblioitemnumber in MARC record, we need it to manage items later...
1408 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblioitem->{biblionumber});
1409 my ($biblioitemnumberfield,$biblioitemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'biblioitems.biblioitemnumber',$frameworkcode);
1410 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1411 my $field=$record->field($biblioitemnumberfield);
1412 $field->update($biblioitemnumbersubfield => "$biblioitemnumber");
1413 $biblioitem->{marc} = $record->as_usmarc();
1414 $biblioitem->{marcxml} = $record->as_xml_record();
1416 $sth = $dbh->prepare( "insert into biblioitems set
1417 biblioitemnumber = ?, biblionumber = ?,
1418 volume = ?, number = ?,
1419 classification = ?, itemtype = ?,
1421 issn = ?, dewey = ?,
1422 subclass = ?, publicationyear = ?,
1423 publishercode = ?, volumedate = ?,
1424 volumeddesc = ?, illus = ?,
1425 pages = ?, notes = ?,
1427 marc = ?, place = ?,
1431 $biblioitemnumber, $biblioitem->{'biblionumber'},
1432 $biblioitem->{'volume'}, $biblioitem->{'number'},
1433 $biblioitem->{'classification'}, $biblioitem->{'itemtype'},
1434 $biblioitem->{'url'}, $biblioitem->{'isbn'},
1435 $biblioitem->{'issn'}, $biblioitem->{'dewey'},
1436 $biblioitem->{'subclass'}, $biblioitem->{'publicationyear'},
1437 $biblioitem->{'publishercode'}, $biblioitem->{'volumedate'},
1438 $biblioitem->{'volumeddesc'}, $biblioitem->{'illus'},
1439 $biblioitem->{'pages'}, $biblioitem->{'bnotes'},
1440 $biblioitem->{'size'}, $biblioitem->{'lccn'},
1441 $biblioitem->{'marc'}, $biblioitem->{'place'},
1442 $biblioitem->{marcxml},
1444 $dbh->do("unlock tables");
1445 z3950_extended_services('update',set_service_options('update'),$record);
1446 z3950_extended_services('commit');
1447 return ($biblioitemnumber);
1450 =head2 REALnewsubtitle
1452 REALnewsubtitle($dbh,$bibnum,$subtitle);
1456 create a new subtitle
1461 sub REALnewsubtitle {
1462 my ( $dbh, $bibnum, $subtitle ) = @_;
1465 "insert into bibliosubtitle set biblionumber = ?, subtitle = ?");
1466 $sth->execute( $bibnum, $subtitle ) if $subtitle;
1472 ($itemnumber,$errors)= REALnewitems($dbh,$item,$barcode);
1476 create a item. $item is a hash and $barcode the barcode.
1483 my ( $dbh, $item, $barcode ) = @_;
1485 # warn "OLDNEWITEMS";
1487 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE,marc_subfield_structure WRITE');
1488 my $sth = $dbh->prepare("Select max(itemnumber) from items");
1493 $data = $sth->fetchrow_hashref;
1494 $itemnumber = $data->{'max(itemnumber)'} + 1;
1496 # FIXME the "notforloan" field seems to be named "loan" in some places. workaround bugfix.
1497 if ( $item->{'loan'} ) {
1498 $item->{'notforloan'} = $item->{'loan'};
1500 # $item->{'biblioitemnumber'} = 1;
1501 # if dateaccessioned is provided, use it. Otherwise, set to NOW()
1502 if ( $item->{'dateaccessioned'} ) {
1503 $sth = $dbh->prepare( "Insert into items set
1504 itemnumber = ?, biblionumber = ?,
1505 multivolumepart = ?,
1506 biblioitemnumber = ?, barcode = ?,
1507 booksellerid = ?, dateaccessioned = ?,
1508 homebranch = ?, holdingbranch = ?,
1509 price = ?, replacementprice = ?,
1510 replacementpricedate = NOW(), datelastseen = NOW(),
1511 multivolume = ?, stack = ?,
1512 itemlost = ?, wthdrawn = ?,
1513 paidfor = ?, itemnotes = ?,
1514 itemcallnumber =?, notforloan = ?,
1519 $itemnumber, $item->{'biblionumber'},
1520 $item->{'multivolumepart'},
1521 $item->{'biblioitemnumber'},$item->{barcode},
1522 $item->{'booksellerid'}, $item->{'dateaccessioned'},
1523 $item->{'homebranch'}, $item->{'holdingbranch'},
1524 $item->{'price'}, $item->{'replacementprice'},
1525 $item->{multivolume}, $item->{stack},
1526 $item->{itemlost}, $item->{wthdrawn},
1527 $item->{paidfor}, $item->{'itemnotes'},
1528 $item->{'itemcallnumber'}, $item->{'notforloan'},
1531 if ( defined $sth->errstr ) {
1532 $error .= $sth->errstr;
1536 $sth = $dbh->prepare( "Insert into items set
1537 itemnumber = ?, biblionumber = ?,
1538 multivolumepart = ?,
1539 biblioitemnumber = ?, barcode = ?,
1540 booksellerid = ?, dateaccessioned = NOW(),
1541 homebranch = ?, holdingbranch = ?,
1542 price = ?, replacementprice = ?,
1543 replacementpricedate = NOW(), datelastseen = NOW(),
1544 multivolume = ?, stack = ?,
1545 itemlost = ?, wthdrawn = ?,
1546 paidfor = ?, itemnotes = ?,
1547 itemcallnumber =?, notforloan = ?,
1552 $itemnumber, $item->{'biblionumber'},
1553 $item->{'multivolumepart'},
1554 $item->{'biblioitemnumber'},$item->{barcode},
1555 $item->{'booksellerid'},
1556 $item->{'homebranch'}, $item->{'holdingbranch'},
1557 $item->{'price'}, $item->{'replacementprice'},
1558 $item->{multivolume}, $item->{stack},
1559 $item->{itemlost}, $item->{wthdrawn},
1560 $item->{paidfor}, $item->{'itemnotes'},
1561 $item->{'itemcallnumber'}, $item->{'notforloan'},
1564 if ( defined $sth->errstr ) {
1565 $error .= $sth->errstr;
1568 # item stored, now, deal with the marc part...
1569 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1570 where biblio.biblionumber=biblioitems.biblionumber and
1571 biblio.biblionumber=?");
1572 $sth->execute($item->{biblionumber});
1573 if ( defined $sth->errstr ) {
1574 $error .= $sth->errstr;
1576 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1577 warn "ERROR IN REALnewitem, MARC record not found FOR $item->{biblionumber} => $rawmarc <=" unless $rawmarc;
1578 my $record = MARC::File::USMARC::decode($rawmarc);
1579 # ok, we have the marc record, add item number to the item field (in {marc}, and add the field to the record)
1580 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1581 my $itemrecord = MARC::Record->new_from_usmarc($item->{marc});
1583 #warn $itemnumberfield;
1584 #warn $itemrecord->field($itemnumberfield);
1585 my $itemfield = $itemrecord->field($itemnumberfield);
1586 $itemfield->add_subfields($itemnumbersubfield => "$itemnumber");
1587 $record->insert_grouped_field($itemfield);
1588 # save the record into biblioitem
1589 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=?");
1590 $sth->execute($record->as_usmarc(),$record->as_xml_record(),$item->{biblionumber});
1591 if ( defined $sth->errstr ) {
1592 $error .= $sth->errstr;
1594 z3950_extended_services('update',set_service_options('update'),$record);
1595 z3950_extended_services('commit');
1596 $dbh->do('unlock tables');
1597 return ( $itemnumber, $error );
1600 =head2 REALmoditem($dbh,$item);
1611 my ( $dbh, $item ) = @_;
1612 $item->{'bibitemnum'} = 1;
1614 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE');
1615 $item->{'itemnum'} = $item->{'itemnumber'} unless $item->{'itemnum'};
1616 my $query = "update items set barcode=?,itemnotes=?,itemcallnumber=?,notforloan=?,location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1618 $item->{'barcode'}, $item->{'itemnotes'},
1619 $item->{'itemcallnumber'}, $item->{'notforloan'},
1620 $item->{'location'}, $item->{multivolumepart},
1621 $item->{multivolume}, $item->{stack},
1624 if ( $item->{'lost'} ne '' ) {
1625 $query = "update items set biblioitemnumber=?,barcode=?,itemnotes=?,homebranch=?,
1626 itemlost=?,wthdrawn=?,itemcallnumber=?,notforloan=?,
1627 location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1629 $item->{'bibitemnum'}, $item->{'barcode'},
1630 $item->{'itemnotes'}, $item->{'homebranch'},
1631 $item->{'lost'}, $item->{'wthdrawn'},
1632 $item->{'itemcallnumber'}, $item->{'notforloan'},
1633 $item->{'location'}, $item->{multivolumepart},
1634 $item->{multivolume}, $item->{stack},
1637 if ($item->{homebranch}) {
1638 $query.=",homebranch=?";
1639 push @bind, $item->{homebranch};
1641 if ($item->{holdingbranch}) {
1642 $query.=",holdingbranch=?";
1643 push @bind, $item->{holdingbranch};
1646 $query.=" where itemnumber=?";
1647 push @bind,$item->{'itemnum'};
1648 if ( $item->{'replacement'} ne '' ) {
1649 $query =~ s/ where/,replacementprice='$item->{'replacement'}' where/;
1651 my $sth = $dbh->prepare($query);
1652 $sth->execute(@bind);
1654 # item stored, now, deal with the marc part...
1655 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1656 where biblio.biblionumber=biblioitems.biblionumber and
1657 biblio.biblionumber=? and
1658 biblioitems.biblioitemnumber=?");
1659 $sth->execute($item->{biblionumber},$item->{biblioitemnumber});
1660 if ( defined $sth->errstr ) {
1661 $error .= $sth->errstr;
1663 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1664 # warn "ERROR IN REALmoditem, MARC record not found" unless $rawmarc;
1665 # my $record = MARC::File::USMARC::decode($rawmarc);
1666 my $record=C4::Search::get_record($item->{biblionumber});
1668 # ok, we have the marc record, find the previous item record for this itemnumber and delete it
1669 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1670 # prepare the new item record
1671 my $itemrecord = MARC::File::USMARC::decode($item->{marc});
1672 my $itemfield = $itemrecord->field($itemnumberfield);
1674 # $itemfield->add_subfields($itemnumbersubfield => '$itemnumber');
1675 # parse all fields fields from the complete record
1676 foreach ($record->field($itemnumberfield)) {
1677 # when the previous field is found, replace by the new one
1678 if ($_->subfield($itemnumbersubfield) == $item->{itemnum}) {
1679 $_->replace_with($itemfield);
1682 my $temptest = $_->subfield($itemnumbersubfield);
1683 warn " failed itemnum is $item->{itemnum} and value in record is $temptest";
1686 # $record->insert_grouped_field($itemfield);
1687 # save the record into biblioitem
1688 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=? and biblioitemnumber=?");
1689 $sth->execute($record->as_usmarc(),$record->as_xml_record(),$item->{biblionumber},$item->{biblioitemnumber});
1690 z3950_extended_services('update',set_service_options('update'),$record);
1691 z3950_extended_services('commit');
1692 if ( defined $sth->errstr ) {
1693 $error .= $sth->errstr;
1695 $dbh->do('unlock tables');
1699 =head2 REALdelitem($dbh,$itemnum);
1710 my ( $dbh, $itemnum ) = @_;
1712 # my $dbh=C4Connect;
1713 my $sth = $dbh->prepare("select * from items where itemnumber=?");
1714 $sth->execute($itemnum);
1715 my $data = $sth->fetchrow_hashref;
1717 my $query = "Insert into deleteditems set ";
1719 foreach my $temp ( keys %$data ) {
1720 $query .= "$temp = ?,";
1721 push ( @bind, $data->{$temp} );
1726 $sth = $dbh->prepare($query);
1727 $sth->execute(@bind);
1729 $sth = $dbh->prepare("Delete from items where itemnumber=?");
1730 $sth->execute($itemnum);
1736 =head2 REALdelbiblioitem($dbh,$biblioitemnumber);
1740 deletes a biblioitem
1741 NOTE : not standard sub name. Should be REALdelbiblioitem()
1747 sub REALdelbiblioitem {
1748 my ( $dbh, $biblioitemnumber ) = @_;
1750 # my $dbh = C4Connect;
1751 my $sth = $dbh->prepare( "Select * from biblioitems
1752 where biblioitemnumber = ?"
1756 $sth->execute($biblioitemnumber);
1758 if ( $results = $sth->fetchrow_hashref ) {
1762 "Insert into deletedbiblioitems (biblioitemnumber, biblionumber, volume, number, classification, itemtype,
1763 isbn, issn ,dewey ,subclass ,publicationyear ,publishercode ,volumedate ,volumeddesc ,timestamp ,illus ,
1764 pages ,notes ,size ,url ,lccn ) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
1768 $results->{biblioitemnumber}, $results->{biblionumber},
1769 $results->{volume}, $results->{number},
1770 $results->{classification}, $results->{itemtype},
1771 $results->{isbn}, $results->{issn},
1772 $results->{dewey}, $results->{subclass},
1773 $results->{publicationyear}, $results->{publishercode},
1774 $results->{volumedate}, $results->{volumeddesc},
1775 $results->{timestamp}, $results->{illus},
1776 $results->{pages}, $results->{notes},
1777 $results->{size}, $results->{url},
1781 $dbh->prepare("Delete from biblioitems where biblioitemnumber = ?");
1782 $sth2->execute($biblioitemnumber);
1787 # Now delete all the items attached to the biblioitem
1788 $sth = $dbh->prepare("Select * from items where biblioitemnumber = ?");
1789 $sth->execute($biblioitemnumber);
1791 while ( my $data = $sth->fetchrow_hashref ) {
1792 my $query = "Insert into deleteditems set ";
1794 foreach my $temp ( keys %$data ) {
1795 $query .= "$temp = ?,";
1796 push ( @bind, $data->{$temp} );
1799 my $sth2 = $dbh->prepare($query);
1800 $sth2->execute(@bind);
1803 $sth = $dbh->prepare("Delete from items where biblioitemnumber = ?");
1804 $sth->execute($biblioitemnumber);
1808 } # sub deletebiblioitem
1810 =head2 REALdelbiblio($dbh,$biblio);
1821 my ( $dbh, $biblio ) = @_;
1822 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
1823 $sth->execute($biblio);
1824 if ( my $data = $sth->fetchrow_hashref ) {
1826 my $query = "Insert into deletedbiblio set ";
1828 foreach my $temp ( keys %$data ) {
1829 $query .= "$temp = ?,";
1830 push ( @bind, $data->{$temp} );
1833 #replacing the last , by ",?)"
1835 $sth = $dbh->prepare($query);
1836 $sth->execute(@bind);
1838 $sth = $dbh->prepare("Delete from biblio where biblionumber=?");
1839 $sth->execute($biblio);
1847 $number = itemcount($biblio);
1851 returns the number of items attached to a biblio
1859 my $dbh = C4::Context->dbh;
1862 my $sth = $dbh->prepare("Select count(*) from items where biblionumber=?");
1863 $sth->execute($biblio);
1864 my $data = $sth->fetchrow_hashref;
1866 return ( $data->{'count(*)'} );
1871 $biblionumber = newbiblio($biblio);
1875 create a biblio. The parameter is a hash
1883 my $dbh = C4::Context->dbh;
1884 my $bibnum = REALnewbiblio( $dbh, $biblio );
1885 # finds new (MARC bibid
1886 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1887 # my $record = &MARCkoha2marcBiblio( $dbh, $bibnum );
1888 # MARCaddbiblio( $dbh, $record, $bibnum,'' );
1894 $biblionumber = &modbiblio($biblio);
1898 Update a biblio record.
1900 C<$biblio> is a reference-to-hash whose keys are the fields in the
1901 biblio table in the Koha database. All fields must be present, not
1902 just the ones you wish to change.
1904 C<&modbiblio> updates the record defined by
1905 C<$biblio-E<gt>{biblionumber}> with the values in C<$biblio>.
1907 C<&modbiblio> returns C<$biblio-E<gt>{biblionumber}> whether it was
1916 my $dbh = C4::Context->dbh;
1917 my $biblionumber=REALmodbiblio($dbh,$biblio);
1918 my $record = MARCkoha2marcBiblio($dbh,$biblionumber,$biblionumber);
1919 # finds new (MARC bibid
1920 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$biblionumber);
1921 MARCmodbiblio($dbh,$bibid,$record,"",0);
1922 return($biblionumber);
1925 =head2 &modsubtitle($biblionumber, $subtitle);
1929 Sets the subtitle of a book.
1931 C<$biblionumber> is the biblionumber of the book to modify.
1933 C<$subtitle> is the new subtitle.
1940 my ( $bibnum, $subtitle ) = @_;
1941 my $dbh = C4::Context->dbh;
1942 &REALmodsubtitle( $dbh, $bibnum, $subtitle );
1945 =head2 &modaddauthor($biblionumber, $author);
1949 Replaces all additional authors for the book with biblio number
1950 C<$biblionumber> with C<$author>. If C<$author> is the empty string,
1951 C<&modaddauthor> deletes all additional authors.
1958 my ( $bibnum, @authors ) = @_;
1959 my $dbh = C4::Context->dbh;
1960 &REALmodaddauthor( $dbh, $bibnum, @authors );
1961 } # sub modaddauthor
1965 $error = &modsubject($biblionumber, $force, @subjects);
1969 $force - a subject to force
1970 $error - Error message, or undef if successful.
1977 my ( $bibnum, $force, @subject ) = @_;
1978 my $dbh = C4::Context->dbh;
1979 my $error = &REALmodsubject( $dbh, $bibnum, $force, @subject );
1981 # When MARC is off, ensures that the MARC biblio table gets updated with new
1982 # subjects, of course, it deletes the biblio in marc, and then recreates.
1983 # This check is to ensure that no MARC data exists to lose.
1984 # if (C4::Context->preference("MARC") eq '0'){
1985 # warn "in modSUBJECT";
1986 # my $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibnum);
1987 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1988 # &MARCmodbiblio($dbh,$bibid, $MARCRecord);
1994 =head2 modbibitem($dbh, $biblioitem);
1998 modify a biblioitem. The parameter is a hash
2005 my ($dbh, $biblioitem) = @_;
2006 #my $dbh = C4::Context->dbh;
2007 &REALmodbiblioitem( $dbh, $biblioitem );
2010 =head2 newbiblioitem
2012 $biblioitemnumber = newbiblioitem($biblioitem)
2016 create a biblioitem, the parameter is a hash
2023 my ($dbh, $biblioitem) = @_;
2024 #my $dbh = C4::Context->dbh;
2025 # add biblio information to the hash
2026 my $MARCbiblio = MARCkoha2marcBiblio( $dbh, $biblioitem );
2027 $biblioitem->{marc} = $MARCbiblio->as_usmarc();
2028 my $bibitemnum = &REALnewbiblioitem( $dbh, $biblioitem );
2029 return ($bibitemnum);
2032 =head2 newsubtitle($biblionumber,$subtitle);
2036 insert a subtitle for $biblionumber biblio
2044 my ( $bibnum, $subtitle ) = @_;
2045 my $dbh = C4::Context->dbh;
2046 &REALnewsubtitle( $dbh, $bibnum, $subtitle );
2051 $errors = newitems($dbh, $item, @barcodes);
2055 insert items ($item is a hash)
2063 my ( $dbh, $item, @barcodes ) = @_;
2064 #my $dbh = C4::Context->dbh;
2068 foreach my $barcode (@barcodes) {
2069 # add items, one by one for each barcode.
2071 $oneitem->{barcode}= $barcode;
2072 my $MARCitem = &MARCkoha2marcItem( $dbh, $oneitem);
2073 $oneitem->{marc} = $MARCitem->as_usmarc;
2074 ( $itemnumber, $error ) = &REALnewitems( $dbh, $oneitem);
2075 # $errors .= $error;
2076 # &MARCadditem( $dbh, $MARCitem, $item->{biblionumber} );
2081 =head2 moditem($dbh,$item);
2085 modify an item ($item is a hash with all item informations)
2093 my ($dbh, $item) = @_;
2094 #my $dbh = C4::Context->dbh;
2095 &REALmoditem( $dbh, $item );
2097 &MARCkoha2marcItem( $dbh, $item->{'biblionumber'}, $item->{'itemnum'} );
2099 &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $item->{biblionumber} );
2100 &MARCmoditem( $dbh, $MARCitem, $bibid, $item->{itemnum}, 0 );
2105 $error = checkitems($count,@barcodes);
2109 check for each @barcode entry that the barcode is not a duplicate
2116 my ( $count, @barcodes ) = @_;
2117 my $dbh = C4::Context->dbh;
2119 my $sth = $dbh->prepare("Select * from items where barcode=?");
2120 for ( my $i = 0 ; $i < $count ; $i++ ) {
2121 $barcodes[$i] = uc $barcodes[$i];
2122 $sth->execute( $barcodes[$i] );
2123 if ( my $data = $sth->fetchrow_hashref ) {
2124 $error .= " Duplicate Barcode: $barcodes[$i]";
2131 =head2 delitem($itemnum);
2135 delete item $itemnum being the item number to delete
2143 my $dbh = C4::Context->dbh;
2144 &REALdelitem( $dbh, $itemnum );
2147 =head2 deletebiblioitem($biblioitemnumber);
2151 delete the biblioitem $biblioitemnumber
2157 sub deletebiblioitem {
2158 my ($biblioitemnumber) = @_;
2159 my $dbh = C4::Context->dbh;
2160 &REALdelbiblioitem( $dbh, $biblioitemnumber );
2161 } # sub deletebiblioitem
2163 =head2 delbiblio($biblionumber)
2167 delete biblio $biblionumber
2175 my $dbh = C4::Context->dbh;
2176 &REALdelbiblio( $dbh, $biblio );
2177 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $biblio );
2178 &MARCdelbiblio( $dbh, $bibid, 0 );
2183 ($count,@results) = getbiblio($biblionumber);
2187 return an array with hash of biblios.
2189 FIXME : biblionumber being the primary key, this sub will always return only 1 result, API should be modified...
2196 my ($biblionumber) = @_;
2197 my $dbh = C4::Context->dbh;
2198 my $sth = $dbh->prepare("Select * from biblio where biblionumber = ?");
2200 # || die "Cannot prepare $query\n" . $dbh->errstr;
2204 $sth->execute($biblionumber);
2206 # || die "Cannot execute $query\n" . $sth->errstr;
2207 while ( my $data = $sth->fetchrow_hashref ) {
2208 $results[$count] = $data;
2213 return ( $count, @results );
2218 $data = &bibdata($biblionumber, $type);
2220 Returns information about the book with the given biblionumber.
2222 C<$type> is ignored.
2224 C<&bibdata> returns a reference-to-hash. The keys are the fields in
2225 the C<biblio>, C<biblioitems>, and C<bibliosubtitle> tables in the
2228 In addition, C<$data-E<gt>{subject}> is the list of the book's
2229 subjects, separated by C<" , "> (space, comma, space).
2231 If there are multiple biblioitems with the given biblionumber, only
2232 the first one is considered.
2237 my ($bibnum, $type) = @_;
2238 my $dbh = C4::Context->dbh;
2239 my $sth = $dbh->prepare("Select *, biblioitems.notes AS bnotes, biblio.notes
2241 left join biblioitems on biblioitems.biblionumber = biblio.biblionumber
2242 left join bibliosubtitle on
2243 biblio.biblionumber = bibliosubtitle.biblionumber
2244 left join itemtypes on biblioitems.itemtype=itemtypes.itemtype
2245 where biblio.biblionumber = ?
2247 $sth->execute($bibnum);
2249 $data = $sth->fetchrow_hashref;
2251 # handle management of repeated subtitle
2252 $sth = $dbh->prepare("Select * from bibliosubtitle where biblionumber = ?");
2253 $sth->execute($bibnum);
2255 while (my $dat = $sth->fetchrow_hashref){
2257 $line{subtitle} = $dat->{subtitle};
2258 push @subtitles, \%line;
2260 $data->{subtitles} = \@subtitles;
2262 $sth = $dbh->prepare("Select * from bibliosubject where biblionumber = ?");
2263 $sth->execute($bibnum);
2265 while (my $dat = $sth->fetchrow_hashref){
2267 $line{subject} = $dat->{'subject'};
2268 push @subjects, \%line;
2270 $data->{subjects} = \@subjects;
2272 $sth = $dbh->prepare("Select * from additionalauthors where biblionumber = ?");
2273 $sth->execute($bibnum);
2274 while (my $dat = $sth->fetchrow_hashref){
2275 $data->{'additionalauthors'} .= "$dat->{'author'} - ";
2277 chop $data->{'additionalauthors'};
2278 chop $data->{'additionalauthors'};
2279 chop $data->{'additionalauthors'};
2284 =head2 getbiblioitem
2286 ($count,@results) = getbiblioitem($biblioitemnumber);
2290 return an array with hash of biblioitemss.
2292 FIXME : biblioitemnumber being unique, this sub will always return only 1 result, API should be modified...
2299 my ($biblioitemnum) = @_;
2300 my $dbh = C4::Context->dbh;
2301 my $sth = $dbh->prepare( "Select * from biblioitems where
2302 biblioitemnumber = ?"
2307 $sth->execute($biblioitemnum);
2309 while ( my $data = $sth->fetchrow_hashref ) {
2310 $results[$count] = $data;
2315 return ( $count, @results );
2316 } # sub getbiblioitem
2318 =head2 getbiblioitembybiblionumber
2320 ($count,@results) = getbiblioitembybiblionumber($biblionumber);
2324 return an array with hash of biblioitems for the given biblionumber.
2330 sub getbiblioitembybiblionumber {
2331 my ($biblionumber) = @_;
2332 my $dbh = C4::Context->dbh;
2333 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?");
2337 $sth->execute($biblionumber);
2339 while ( my $data = $sth->fetchrow_hashref ) {
2340 $results[$count] = $data;
2345 return ( $count, @results );
2348 =head2 getitemsbybiblioitem
2350 ($count,@results) = getitemsbybiblioitem($biblionumber);
2354 returns an array with hash of items
2360 sub getitemsbybiblioitem {
2361 my ($biblioitemnum) = @_;
2362 my $dbh = C4::Context->dbh;
2363 my $sth = $dbh->prepare( "Select * from items, biblio where
2364 biblio.biblionumber = items.biblionumber and biblioitemnumber
2368 # || die "Cannot prepare $query\n" . $dbh->errstr;
2372 $sth->execute($biblioitemnum);
2374 # || die "Cannot execute $query\n" . $sth->errstr;
2375 while ( my $data = $sth->fetchrow_hashref ) {
2376 $results[$count] = $data;
2381 return ( $count, @results );
2382 } # sub getitemsbybiblioitem
2386 @results = &ItemInfo($env, $biblionumber, $type);
2388 Returns information about books with the given biblionumber.
2390 C<$type> may be either C<intra> or anything else. If it is not set to
2391 C<intra>, then the search will exclude lost, very overdue, and
2396 C<&ItemInfo> returns a list of references-to-hash. Each element
2397 contains a number of keys. Most of them are table items from the
2398 C<biblio>, C<biblioitems>, C<items>, and C<itemtypes> tables in the
2399 Koha database. Other keys include:
2403 =item C<$data-E<gt>{branchname}>
2405 The name (not the code) of the branch to which the book belongs.
2407 =item C<$data-E<gt>{datelastseen}>
2409 This is simply C<items.datelastseen>, except that while the date is
2410 stored in YYYY-MM-DD format in the database, here it is converted to
2411 DD/MM/YYYY format. A NULL date is returned as C<//>.
2413 =item C<$data-E<gt>{datedue}>
2415 =item C<$data-E<gt>{class}>
2417 This is the concatenation of C<biblioitems.classification>, the book's
2418 Dewey code, and C<biblioitems.subclass>.
2420 =item C<$data-E<gt>{ocount}>
2422 I think this is the number of copies of the book available.
2424 =item C<$data-E<gt>{order}>
2426 If this is set, it is set to C<One Order>.
2433 my ($env,$biblionumber,$type) = @_;
2434 my $dbh = C4::Context->dbh;
2435 my $query = "SELECT *,items.notforloan as itemnotforloan FROM items, biblio, biblioitems
2436 left join itemtypes on biblioitems.itemtype = itemtypes.itemtype
2437 WHERE items.biblionumber = ?
2438 AND biblioitems.biblioitemnumber = items.biblioitemnumber
2439 AND biblio.biblionumber = items.biblionumber";
2440 $query .= " order by items.dateaccessioned desc";
2441 my $sth=$dbh->prepare($query);
2442 $sth->execute($biblionumber);
2445 while (my $data=$sth->fetchrow_hashref){
2447 my $isth=$dbh->prepare("Select issues.*,borrowers.cardnumber from issues,borrowers where itemnumber = ? and returndate is null and issues.borrowernumber=borrowers.borrowernumber");
2448 $isth->execute($data->{'itemnumber'});
2449 if (my $idata=$isth->fetchrow_hashref){
2450 $data->{borrowernumber} = $idata->{borrowernumber};
2451 $data->{cardnumber} = $idata->{cardnumber};
2452 $datedue = format_date($idata->{'date_due'});
2454 if ($datedue eq ''){
2455 my ($restype,$reserves)=C4::Reserves2::CheckReserves($data->{'itemnumber'});
2461 #get branch information.....
2462 my $bsth=$dbh->prepare("SELECT * FROM branches WHERE branchcode = ?");
2463 $bsth->execute($data->{'holdingbranch'});
2464 if (my $bdata=$bsth->fetchrow_hashref){
2465 $data->{'branchname'} = $bdata->{'branchname'};
2467 my $date=format_date($data->{'datelastseen'});
2468 $data->{'datelastseen'}=$date;
2469 $data->{'datedue'}=$datedue;
2470 # get notforloan complete status if applicable
2471 my $sthnflstatus = $dbh->prepare('select authorised_value from marc_subfield_structure where kohafield="items.notforloan"');
2472 $sthnflstatus->execute;
2473 my ($authorised_valuecode) = $sthnflstatus->fetchrow;
2474 if ($authorised_valuecode) {
2475 $sthnflstatus = $dbh->prepare("select lib from authorised_values where category=? and authorised_value=?");
2476 $sthnflstatus->execute($authorised_valuecode,$data->{itemnotforloan});
2477 my ($lib) = $sthnflstatus->fetchrow;
2478 $data->{notforloan} = $lib;
2489 ($count, @results) = &bibitems($biblionumber);
2491 Given the biblionumber for a book, C<&bibitems> looks up that book's
2492 biblioitems (different publications of the same book, the audio book
2493 and film versions, etc.).
2495 C<$count> is the number of elements in C<@results>.
2497 C<@results> is an array of references-to-hash; the keys are the fields
2498 of the C<biblioitems> and C<itemtypes> tables of the Koha database. In
2499 addition, C<itemlost> indicates the availability of the item: if it is
2500 "2", then all copies of the item are long overdue; if it is "1", then
2501 all copies are lost; otherwise, there is at least one copy available.
2507 my $dbh = C4::Context->dbh;
2508 my $sth = $dbh->prepare("SELECT biblioitems.*,
2510 MIN(items.itemlost) as itemlost,
2511 MIN(items.dateaccessioned) as dateaccessioned
2512 FROM biblioitems, itemtypes, items
2513 WHERE biblioitems.biblionumber = ?
2514 AND biblioitems.itemtype = itemtypes.itemtype
2515 AND biblioitems.biblioitemnumber = items.biblioitemnumber
2516 GROUP BY items.biblioitemnumber");
2519 $sth->execute($bibnum);
2520 while (my $data = $sth->fetchrow_hashref) {
2521 $results[$count] = $data;
2525 return($count, @results);
2531 $itemdata = &bibitemdata($biblioitemnumber);
2533 Looks up the biblioitem with the given biblioitemnumber. Returns a
2534 reference-to-hash. The keys are the fields from the C<biblio>,
2535 C<biblioitems>, and C<itemtypes> tables in the Koha database, except
2536 that C<biblioitems.notes> is given as C<$itemdata-E<gt>{bnotes}>.
2542 my $dbh = C4::Context->dbh;
2543 my $sth = $dbh->prepare("Select *,biblioitems.notes as bnotes from biblio, biblioitems,itemtypes where biblio.biblionumber = biblioitems.biblionumber and biblioitemnumber = ? and biblioitems.itemtype = itemtypes.itemtype");
2546 $sth->execute($bibitem);
2548 $data = $sth->fetchrow_hashref;
2555 =head2 getbibliofromitemnumber
2557 $item = &getbibliofromitemnumber($env, $dbh, $itemnumber);
2559 Looks up the item with the given itemnumber.
2561 C<$env> and C<$dbh> are ignored.
2563 C<&itemnodata> returns a reference-to-hash whose keys are the fields
2564 from the C<biblio>, C<biblioitems>, and C<items> tables in the Koha
2569 sub getbibliofromitemnumber {
2570 my ($env,$dbh,$itemnumber) = @_;
2571 $dbh = C4::Context->dbh;
2572 my $sth=$dbh->prepare("Select * from biblio,items,biblioitems
2573 where items.itemnumber = ?
2574 and biblio.biblionumber = items.biblionumber
2575 and biblioitems.biblioitemnumber = items.biblioitemnumber");
2577 $sth->execute($itemnumber);
2578 my $data=$sth->fetchrow_hashref;
2585 @barcodes = &barcodes($biblioitemnumber);
2587 Given a biblioitemnumber, looks up the corresponding items.
2589 Returns an array of references-to-hash; the keys are C<barcode> and
2592 The returned items include very overdue items, but not lost ones.
2597 #called from request.pl
2598 my ($biblioitemnumber)=@_;
2599 my $dbh = C4::Context->dbh;
2600 my $sth=$dbh->prepare("SELECT barcode, itemlost, holdingbranch FROM items
2601 WHERE biblioitemnumber = ?
2602 AND (wthdrawn <> 1 OR wthdrawn IS NULL)");
2603 $sth->execute($biblioitemnumber);
2606 while (my $data=$sth->fetchrow_hashref){
2607 $barcodes[$i]=$data;
2617 $item = &itemdata($barcode);
2619 Looks up the item with the given barcode, and returns a
2620 reference-to-hash containing information about that item. The keys of
2621 the hash are the fields from the C<items> and C<biblioitems> tables in
2626 sub get_item_from_barcode {
2628 my $dbh = C4::Context->dbh;
2629 my $sth=$dbh->prepare("Select * from items,biblioitems where barcode=?
2630 and items.biblioitemnumber=biblioitems.biblioitemnumber");
2631 $sth->execute($barcode);
2632 my $data=$sth->fetchrow_hashref;
2640 @issues = &itemissues($biblioitemnumber, $biblio);
2642 Looks up information about who has borrowed the bookZ<>(s) with the
2643 given biblioitemnumber.
2645 C<$biblio> is ignored.
2647 C<&itemissues> returns an array of references-to-hash. The keys
2648 include the fields from the C<items> table in the Koha database.
2649 Additional keys include:
2655 If the item is currently on loan, this gives the due date.
2657 If the item is not on loan, then this is either "Available" or
2658 "Cancelled", if the item has been withdrawn.
2662 If the item is currently on loan, this gives the card number of the
2663 patron who currently has the item.
2665 =item C<timestamp0>, C<timestamp1>, C<timestamp2>
2667 These give the timestamp for the last three times the item was
2670 =item C<card0>, C<card1>, C<card2>
2672 The card number of the last three patrons who borrowed this item.
2674 =item C<borrower0>, C<borrower1>, C<borrower2>
2676 The borrower number of the last three patrons who borrowed this item.
2683 my ($bibitem, $biblio)=@_;
2684 my $dbh = C4::Context->dbh;
2685 # FIXME - If this function die()s, the script will abort, and the
2686 # user won't get anything; depending on how far the script has
2687 # gotten, the user might get a blank page. It would be much better
2688 # to at least print an error message. The easiest way to do this
2689 # is to set $SIG{__DIE__}.
2690 my $sth = $dbh->prepare("Select * from items where
2691 items.biblioitemnumber = ?")
2692 || die $dbh->errstr;
2696 $sth->execute($bibitem)
2697 || die $sth->errstr;
2699 while (my $data = $sth->fetchrow_hashref) {
2700 # Find out who currently has this item.
2701 # FIXME - Wouldn't it be better to do this as a left join of
2702 # some sort? Currently, this code assumes that if
2703 # fetchrow_hashref() fails, then the book is on the shelf.
2704 # fetchrow_hashref() can fail for any number of reasons (e.g.,
2705 # database server crash), not just because no items match the
2707 my $sth2 = $dbh->prepare("select * from issues,borrowers
2708 where itemnumber = ?
2709 and returndate is NULL
2710 and issues.borrowernumber = borrowers.borrowernumber");
2712 $sth2->execute($data->{'itemnumber'});
2713 if (my $data2 = $sth2->fetchrow_hashref) {
2714 $data->{'date_due'} = $data2->{'date_due'};
2715 $data->{'card'} = $data2->{'cardnumber'};
2716 $data->{'borrower'} = $data2->{'borrowernumber'};
2718 if ($data->{'wthdrawn'} eq '1') {
2719 $data->{'date_due'} = 'Cancelled';
2721 $data->{'date_due'} = 'Available';
2727 # Find the last 3 people who borrowed this item.
2728 $sth2 = $dbh->prepare("select * from issues, borrowers
2729 where itemnumber = ?
2730 and issues.borrowernumber = borrowers.borrowernumber
2731 and returndate is not NULL
2732 order by returndate desc,timestamp desc") || die $dbh->errstr;
2733 $sth2->execute($data->{'itemnumber'}) || die $sth2->errstr;
2734 for (my $i2 = 0; $i2 < 2; $i2++) { # FIXME : error if there is less than 3 pple borrowing this item
2735 if (my $data2 = $sth2->fetchrow_hashref) {
2736 $data->{"timestamp$i2"} = $data2->{'timestamp'};
2737 $data->{"card$i2"} = $data2->{'cardnumber'};
2738 $data->{"borrower$i2"} = $data2->{'borrowernumber'};
2743 $results[$i] = $data;
2753 ($count, $subjects) = &getsubject($biblionumber);
2755 Looks up the subjects of the book with the given biblionumber. Returns
2756 a two-element list. C<$subjects> is a reference-to-array, where each
2757 element is a subject of the book, and C<$count> is the number of
2758 elements in C<$subjects>.
2764 my $dbh = C4::Context->dbh;
2765 my $sth=$dbh->prepare("Select * from bibliosubject where biblionumber=?");
2766 $sth->execute($bibnum);
2769 while (my $data=$sth->fetchrow_hashref){
2774 return($i,\@results);
2779 ($count, $authors) = &getaddauthor($biblionumber);
2781 Looks up the additional authors for the book with the given
2784 Returns a two-element list. C<$authors> is a reference-to-array, where
2785 each element is an additional author, and C<$count> is the number of
2786 elements in C<$authors>.
2792 my $dbh = C4::Context->dbh;
2793 my $sth=$dbh->prepare("Select * from additionalauthors where biblionumber=?");
2794 $sth->execute($bibnum);
2797 while (my $data=$sth->fetchrow_hashref){
2802 return($i,\@results);
2808 ($count, $subtitles) = &getsubtitle($biblionumber);
2810 Looks up the subtitles for the book with the given biblionumber.
2812 Returns a two-element list. C<$subtitles> is a reference-to-array,
2813 where each element is a subtitle, and C<$count> is the number of
2814 elements in C<$subtitles>.
2820 my $dbh = C4::Context->dbh;
2821 my $sth=$dbh->prepare("Select * from bibliosubtitle where biblionumber=?");
2822 $sth->execute($bibnum);
2825 while (my $data=$sth->fetchrow_hashref){
2830 return($i,\@results);
2836 ($count, @websites) = &getwebsites($biblionumber);
2838 Looks up the web sites pertaining to the book with the given
2841 C<$count> is the number of elements in C<@websites>.
2843 C<@websites> is an array of references-to-hash; the keys are the
2844 fields from the C<websites> table in the Koha database.
2847 #FIXME : could maybe be deleted. Otherwise, would be better in a Websites.pm package
2848 #(with add / modify / delete subs)
2851 my ($biblionumber) = @_;
2852 my $dbh = C4::Context->dbh;
2853 my $sth = $dbh->prepare("Select * from websites where biblionumber = ?");
2857 $sth->execute($biblionumber);
2858 while (my $data = $sth->fetchrow_hashref) {
2859 # FIXME - The URL scheme shouldn't be stripped off, at least
2860 # not here, since it's part of the URL, and will be useful in
2861 # constructing a link to the site. If you don't want the user
2862 # to see the "http://" part, strip that off when building the
2864 $data->{'url'} =~ s/^http:\/\///; # FIXME - Leaning toothpick
2866 $results[$count] = $data;
2871 return($count, @results);
2874 =head2 getwebbiblioitems
2876 ($count, @results) = &getwebbiblioitems($biblionumber);
2878 Given a book's biblionumber, looks up the web versions of the book
2879 (biblioitems with itemtype C<WEB>).
2881 C<$count> is the number of items in C<@results>. C<@results> is an
2882 array of references-to-hash; the keys are the items from the
2883 C<biblioitems> table of the Koha database.
2887 sub getwebbiblioitems {
2888 my ($biblionumber) = @_;
2889 my $dbh = C4::Context->dbh;
2890 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?
2891 and itemtype = 'WEB'");
2895 $sth->execute($biblionumber);
2896 while (my $data = $sth->fetchrow_hashref) {
2897 $data->{'url'} =~ s/^http:\/\///;
2898 $results[$count] = $data;
2903 return($count, @results);
2904 } # sub getwebbiblioitems
2907 my $NSB = '\x88'; # NSB : begin Non Sorting Block
2908 my $NSE = '\x89'; # NSE : Non Sorting Block end
2909 # handles non sorting blocks
2913 s/[ ]{0,1}$NSE/) /gm;
2920 my $dbh = C4::Context->dbh;
2921 my $result = MARCmarc2koha($dbh,$record,'');
2923 my ($biblionumber,$bibid,$title);
2924 # search duplicate on ISBN, easy and fast...
2925 if ($result->{isbn}) {
2926 $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=?");
2927 $sth->execute($result->{'isbn'});
2928 ($biblionumber,$bibid,$title) = $sth->fetchrow;
2929 return $biblionumber,$bibid,$title if ($biblionumber);
2931 # a more complex search : build a request for SearchMarc::catalogsearch()
2932 my (@tags, @and_or, @excluding, @operator, @value, $offset,$length);
2933 # search on biblio.title
2934 my ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.title","");
2935 if ($record->field($tag)) {
2936 if ($record->field($tag)->subfields($subfield)) {
2937 push @tags, "'".$tag.$subfield."'";
2938 push @and_or, "and";
2939 push @excluding, "";
2940 push @operator, "contains";
2941 push @value, $record->field($tag)->subfield($subfield);
2942 # warn "for title, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2945 # ... and on biblio.author
2946 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.author","");
2947 if ($record->field($tag)) {
2948 if ($record->field($tag)->subfields($subfield)) {
2949 push @tags, "'".$tag.$subfield."'";
2950 push @and_or, "and";
2951 push @excluding, "";
2952 push @operator, "contains";
2953 push @value, $record->field($tag)->subfield($subfield);
2954 # warn "for author, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2957 # ... and on publicationyear.
2958 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publicationyear","");
2959 if ($record->field($tag)) {
2960 if ($record->field($tag)->subfields($subfield)) {
2961 push @tags, "'".$tag.$subfield."'";
2962 push @and_or, "and";
2963 push @excluding, "";
2964 push @operator, "=";
2965 push @value, $record->field($tag)->subfield($subfield);
2966 # warn "for publicationyear, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2970 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.size","");
2971 if ($record->field($tag)) {
2972 if ($record->field($tag)->subfields($subfield)) {
2973 push @tags, "'".$tag.$subfield."'";
2974 push @and_or, "and";
2975 push @excluding, "";
2976 push @operator, "=";
2977 push @value, $record->field($tag)->subfield($subfield);
2978 # warn "for size, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2981 # ... and on publisher.
2982 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publishercode","");
2983 if ($record->field($tag)) {
2984 if ($record->field($tag)->subfields($subfield)) {
2985 push @tags, "'".$tag.$subfield."'";
2986 push @and_or, "and";
2987 push @excluding, "";
2988 push @operator, "=";
2989 push @value, $record->field($tag)->subfield($subfield);
2990 # warn "for publishercode, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2993 # ... and on volume.
2994 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.volume","");
2995 if ($record->field($tag)) {
2996 if ($record->field($tag)->subfields($subfield)) {
2997 push @tags, "'".$tag.$subfield."'";
2998 push @and_or, "and";
2999 push @excluding, "";
3000 push @operator, "=";
3001 push @value, $record->field($tag)->subfield($subfield);
3002 # warn "for volume, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
3006 my ($finalresult,$nbresult) = C4::SearchMarc::catalogsearch($dbh,\@tags,\@and_or,\@excluding,\@operator,\@value,0,10);
3007 # there is at least 1 result => return the 1st one
3009 # warn "$nbresult => ".@$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
3010 return @$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
3012 # no result, returns nothing
3019 if(substr($isbn, 0, 1) <=7) {
3020 $seg1 = substr($isbn, 0, 1);
3021 } elsif(substr($isbn, 0, 2) <= 94) {
3022 $seg1 = substr($isbn, 0, 2);
3023 } elsif(substr($isbn, 0, 3) <= 995) {
3024 $seg1 = substr($isbn, 0, 3);
3025 } elsif(substr($isbn, 0, 4) <= 9989) {
3026 $seg1 = substr($isbn, 0, 4);
3028 $seg1 = substr($isbn, 0, 5);
3030 my $x = substr($isbn, length($seg1));
3032 if(substr($x, 0, 2) <= 19) {
3033 # if(sTmp2 < 10) sTmp2 = "0" sTmp2;
3034 $seg2 = substr($x, 0, 2);
3035 } elsif(substr($x, 0, 3) <= 699) {
3036 $seg2 = substr($x, 0, 3);
3037 } elsif(substr($x, 0, 4) <= 8399) {
3038 $seg2 = substr($x, 0, 4);
3039 } elsif(substr($x, 0, 5) <= 89999) {
3040 $seg2 = substr($x, 0, 5);
3041 } elsif(substr($x, 0, 6) <= 9499999) {
3042 $seg2 = substr($x, 0, 6);
3044 $seg2 = substr($x, 0, 7);
3046 my $seg3=substr($x,length($seg2));
3047 $seg3=substr($seg3,0,length($seg3)-1) ;
3048 my $seg4 = substr($x, -1, 1);
3049 return "$seg1-$seg2-$seg3-$seg4";
3053 END { } # module clean-up code here (global destructor)
3059 Koha Developement team <info@koha.org>
3061 Paul POULAIN paul.poulain@free.fr
3067 # Revision 1.170 2006/04/15 02:47:47 tgarip1957
3068 # Change the MARC Leader to UTF-8 incase user did not set it. Important for Zebra.
3069 # The new M::F::XML is sensitive to leader settings
3071 # Revision 1.169 2006/04/10 20:39:49 tgarip1957
3072 # New sub to use by Circ2.pm . Allows one subfield of MARC holdings fields to be updated to use with branch transfer(holdingbranch) and onloan flag when set
3074 # Revision 1.168 2006/04/03 04:00:02 rangi
3075 # Modify item now works
3077 # BUT only if there is only one item, if there is more than one item, it gets messed up.
3078 # They get combined into the form, ill work on this next
3080 # Revision 1.167 2006/04/03 02:12:49 kados
3081 # some modifs to improve plugin support
3083 # Revision 1.166 2006/04/01 22:10:50 rangi
3084 # Fixing the problem that all items were getting biblioitem=1 set
3086 # Revision 1.165 2006/04/01 21:22:05 rangi
3087 # Adding a little fake subroutine that a few scripts in the opac depend on, can be removed once the opac scripts are rewritten
3089 # Revision 1.164 2006/03/29 01:56:25 rangi
3090 # Delete isnt working using the extended services method
3092 # Revision 1.163 2006/03/28 23:05:08 rangi
3093 # Delete working now
3095 # Revision 1.162 2006/03/13 23:12:44 rangi
3096 # Adding commits, so that changes stick
3098 # Revision 1.161 2006/03/10 02:40:38 kados
3099 # syncing MARChtml2xml wtih rel_2_2, removing unused MARChtml2marc
3101 # Revision 1.160 2006/03/07 22:00:18 kados
3102 # adding support for 'delete' function
3104 # Revision 1.159 2006/03/07 21:54:47 rangi
3105 # Starting work on deletes
3107 # Revision 1.158 2006/03/06 02:45:41 kados
3108 # Adding fixes to MARC editor to HEAD
3110 # Revision 1.157 2006/03/01 03:07:54 kados
3111 # rollback ... by accident I committed a rel_2_2 Biblio.pm
3113 # Revision 1.155 2006/02/27 01:08:31 kados
3114 # Removing 'our Zconn' from top...
3116 # Revision 1.154 2006/02/26 00:08:20 kados
3117 # moving all $Zconn s to z3950_extended_services (currently, nothing
3120 # Revision 1.153 2006/02/25 22:39:10 kados
3121 # Another purely documentation commit. Just changing formatting to ease
3124 # Revision 1.152 2006/02/25 21:17:20 kados
3125 # Purely documentation change: converted all =head2 entries to use function
3126 # name as title rather than usage as title
3128 # Revision 1.151 2006/02/25 21:02:20 kados
3130 # Further cleanup, convering new routines to 4-chars
3132 # Revision 1.150 2006/02/25 20:49:15 kados
3133 # Better documentation, added warning if serviceType is 'drop' since it's
3134 # not supported in Zebra.
3136 # Revision 1.149 2006/02/25 20:30:32 kados
3137 # IMPORTANT: Paul, I've removed the decode_char routine because it's no
3138 # longer necessary. If we need to convert from MARC-8 for display, we should:
3141 # 2. do it with MARC::Charset
3143 # If you still need it, let me know and I'll put it back in.
3145 # Revision 1.148 2006/02/25 19:23:01 kados
3146 # cleaning up POD docs, deleting zebra_create as it's no longer used (
3147 # replaced by z3950_extended_services).
3149 # Revision 1.147 2006/02/25 19:09:59 kados
3150 # readding some lost subs
3152 # Revision 1.145 2006/02/22 01:02:39 kados
3153 # Replacing all calls to zebra_update with calls to
3154 # z3950_extended_services. More work coming, but it's
3157 # Revision 1.144 2006/02/20 14:22:38 kados
3160 # Revision 1.143 2006/02/20 13:26:11 kados
3161 # A new subroutine to handle Z39.50 extended services. You pass it a
3162 # connection object, service type, service options, and a record, and
3163 # it performs the service and handles any exception found.
3165 # Revision 1.142 2006/02/16 20:49:56 kados
3166 # destroy a connection after we're done -- we really should just have one
3167 # connection object and not destroy it until the whole transaction is
3168 # finished -- but this will do for now
3170 # Revision 1.141 2006/02/16 19:47:22 rangi
3171 # Trying to error trap a little more.
3173 # Revision 1.140 2006/02/14 21:36:03 kados
3174 # adding a 'use ZOOM' to biblio.pm, needed for non-mod_perl install.
3175 # also adding diagnostic error if not able to connect to Zebra
3177 # Revision 1.139 2006/02/14 19:53:25 rangi
3178 # Just a little missing my
3180 # Seems to be working great Paul, and I like what you did with zebradb
3182 # Revision 1.138 2006/02/14 11:25:22 tipaul
3183 # road to 3.0 : updating a biblio in zebra seems to work. Still working on it, there are probably some bugs !
3185 # Revision 1.137 2006/02/13 16:34:26 tipaul
3186 # fixing some warnings (perl -w should be quiet)
3188 # Revision 1.136 2006/01/10 17:01:29 tipaul
3189 # adding a XMLgetbiblio in Biblio.pm (1st draft, to use with zebra)
3191 # Revision 1.135 2006/01/06 16:39:37 tipaul
3192 # synch'ing head and rel_2_2 (from 2.2.5, including npl templates)
3193 # Seems not to break too many things, but i'm probably wrong here.
3194 # at least, new features/bugfixes from 2.2.5 are here (tested on some features on my head local copy)
3196 # - removing useless directories (koha-html and koha-plucene)
3198 # Revision 1.134 2006/01/04 15:54:55 tipaul
3199 # utf8 is a : go for beta test in HEAD.
3200 # some explanations :
3201 # - updater/updatedatabase => will transform all tables in innoDB (not related to utf8, just to warn you) AND collate them in utf8 / utf8_general_ci. The SQL command is : ALTER TABLE tablename DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci.
3202 # - *-top.inc will show the pages in utf8
3203 # - THE HARD THING : for me, mysql-client and mysql-server were set up to communicate in iso8859-1, whatever the mysql collation ! Thus, pages were improperly shown, as datas were transmitted in iso8859-1 format ! After a full day of investigation, someone on usenet pointed "set NAMES 'utf8'" to explain that I wanted utf8. I could put this in my.cnf, but if I do that, ALL databases will "speak" in utf8, that's not what we want. Thus, I added a line in Context.pm : everytime a DB handle is opened, the communication is set to utf8.
3204 # - using marcxml field and no more the iso2709 raw marc biblioitems.marc field.
3206 # Revision 1.133 2005/12/12 14:25:51 thd
3209 # Reverse array filled with elements from repeated subfields
3210 # to avoid last to first concatenation of elements in Koha DB.-
3212 # Revision 1.132 2005-10-26 09:12:33 tipaul
3213 # big commit, still breaking things...
3215 # * synch with rel_2_2. Probably the last non manual synch, as rel_2_2 should not be modified deeply.
3216 # * code cleaning (cleaning warnings from perl -w) continued
3218 # Revision 1.131 2005/09/22 10:01:45 tipaul
3219 # see mail on koha-devel : code cleaning on Search.pm + normalizing API + use of biblionumber everywhere (instead of bn, biblio, ...)
3221 # Revision 1.130 2005/09/02 14:34:14 tipaul
3222 # continuing the work to move to zebra. Begin of work for MARC=OFF support.
3223 # IMPORTANT NOTE : the MARCkoha2marc sub API has been modified. Instead of biblionumber & biblioitemnumber, it now gets a hash.
3224 # The sub is used only in Biblio.pm, so the API change should be harmless (except for me, but i'm aware ;-) )
3226 # Revision 1.129 2005/08/12 13:50:31 tipaul
3227 # removing useless sub declarations
3229 # Revision 1.128 2005/08/11 16:12:47 tipaul
3230 # Playing with the zebra...
3232 # * go to koha cvs home directory
3233 # * in misc/zebra there is a unimarc directory. I suggest that marc21 libraries create a marc21 directory
3234 # * put your zebra.cfg files here & create your database.
3235 # * from koha cvs home directory, ln -s misc/zebra/marc21 zebra (I mean create a symbolic link to YOUR zebra directory)
3236 # * now, everytime you add/modify a biblio/item your zebra DB is updated correctly.
3239 # * this uses a system call in perl. CPU consumming, but we are waiting for indexdata Perl/zoom
3240 # * deletion still not work
3241 # * UNIMARC zebra config files are provided in misc/zebra/unimarc directory. The most important line being :
3243 # recordId: (bib1,Local-number)
3247 # elm 090 Local-number -
3248 # elm 090/? Local-number -
3249 # elm 090/?/9 Local-number !:w
3251 # (090$9 being the field mapped to biblio.biblionumber in Koha)
3253 # Revision 1.127 2005/08/11 14:37:32 tipaul
3255 # * removing useless subs
3256 # * removing some subs that are also elsewhere
3257 # * 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)
3259 # Revision 1.126 2005/08/11 09:13:28 tipaul
3260 # just removing useless subs (a lot !!!) for code cleaning
3262 # Revision 1.125 2005/08/11 09:00:07 tipaul
3263 # Ok guys, this time, it seems that item add and modif begin working as expected...
3264 # Still a lot of bugs to fix, of course
3266 # Revision 1.124 2005/08/10 10:21:15 tipaul
3267 # continuing the road to zebra :
3268 # - the biblio add begins to work.
3269 # - the biblio modif begins to work.
3271 # (still without doing anything on zebra)
3272 # (no new change in updatedatabase)
3274 # Revision 1.123 2005/08/09 14:10:28 tipaul
3275 # 1st commit to go to zebra.
3276 # don't update your cvs if you want to have a working head...
3278 # this commit contains :
3279 # * 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...
3280 # * 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.
3281 # * other files : get rid of bibid and use biblionumber instead.
3284 # * does not do anything on zebra yet.
3285 # * if you rename marc_subfield_table, you can't search anymore.
3286 # * you can view a biblio & bibliodetails, go to MARC editor, but NOT save any modif.
3287 # * 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 ;-) )
3289 # 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
3290 # 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.
3292 # tipaul cutted previous commit notes