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
73 MARCfind_MARCbibid_from_oldbiblionumber
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() };
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;
500 =head2 find_biblioitemnumber
502 my $biblioitemnumber = find_biblioitemnumber($dbh,$biblionumber);
506 Returns the 1st biblioitemnumber related to $biblionumber. When MARC=ON we should have 1 biblionumber = 1 and only 1 biblioitemnumber
507 This sub is useless when MARC=OFF
512 sub find_biblioitemnumber {
513 my ( $dbh, $biblionumber ) = @_;
514 my $sth = $dbh->prepare("select biblioitemnumber from biblioitems where biblionumber=?");
515 $sth->execute($biblionumber);
516 my ($biblioitemnumber) = $sth->fetchrow;
517 return $biblioitemnumber;
520 =head2 MARCfind_frameworkcode
522 my $frameworkcode = MARCfind_frameworkcode($dbh,$biblionumber);
526 returns the framework of a given biblio
532 sub MARCfind_frameworkcode {
533 my ( $dbh, $biblionumber ) = @_;
534 my $sth = $dbh->prepare("select frameworkcode from biblio where biblionumber=?");
535 $sth->execute($biblionumber);
536 my ($frameworkcode) = $sth->fetchrow;
537 return $frameworkcode;
540 =head2 MARCkoha2marcBiblio
542 $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibliohash);
546 MARCkoha2marcBiblio is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB biblio/biblioitem :
547 all entries of the hash are transformed into their matching MARC field/subfield.
553 sub MARCkoha2marcBiblio {
555 # this function builds partial MARC::Record from the old koha-DB fields
556 my ( $dbh, $bibliohash ) = @_;
557 # we don't have biblio entries in the hash, so we add them first
558 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
559 $sth->execute($bibliohash->{biblionumber});
560 my $biblio = $sth->fetchrow_hashref;
561 foreach (keys %$biblio) {
562 $bibliohash->{$_}=$biblio->{$_};
564 $sth = $dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
565 my $record = MARC::Record->new();
566 foreach ( keys %$bibliohash ) {
567 &MARCkoha2marcOnefield( $sth, $record, "biblio." . $_, $bibliohash->{$_}, '') if $bibliohash->{$_};
568 &MARCkoha2marcOnefield( $sth, $record, "biblioitems." . $_, $bibliohash->{$_}, '') if $bibliohash->{$_};
571 # other fields => additional authors, subjects, subtitles
572 my $sth2 = $dbh->prepare(" SELECT author FROM additionalauthors WHERE biblionumber=?");
573 $sth2->execute($bibliohash->{biblionumber});
574 while ( my $row = $sth2->fetchrow_hashref ) {
575 &MARCkoha2marcOnefield( $sth, $record, "additionalauthors.author", $bibliohash->{'author'},'' );
577 $sth2 = $dbh->prepare(" SELECT subject FROM bibliosubject WHERE biblionumber=?");
578 $sth2->execute($bibliohash->{biblionumber});
579 while ( my $row = $sth2->fetchrow_hashref ) {
580 &MARCkoha2marcOnefield( $sth, $record, "bibliosubject.subject", $row->{'subject'},'' );
582 $sth2 = $dbh->prepare(" SELECT subtitle FROM bibliosubtitle WHERE biblionumber=?");
583 $sth2->execute($bibliohash->{biblionumber});
584 while ( my $row = $sth2->fetchrow_hashref ) {
585 &MARCkoha2marcOnefield( $sth, $record, "bibliosubtitle.subtitle", $row->{'subtitle'},'' );
591 =head2 MARCkoha2marcItem
593 $MARCRecord = &MARCkoha2marcItem($dbh,$biblionumber,itemnumber);
595 MARCkoha2marcItem is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB items :
596 all entries of the hash are transformed into their matching MARC field/subfield.
604 sub MARCkoha2marcItem {
606 # this function builds partial MARC::Record from the old koha-DB fields
607 my ( $dbh, $item ) = @_;
609 # my $dbh=&C4Connect;
610 my $sth = $dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
611 my $record = MARC::Record->new();
613 foreach( keys %$item ) {
615 &MARCkoha2marcOnefield( $sth, $record, "items." . $_,
622 =head2 MARCkoha2marcOnefield
626 This sub is for internal use only, used by koha2marcBiblio & koha2marcItem
632 sub MARCkoha2marcOnefield {
633 my ( $sth, $record, $kohafieldname, $value,$frameworkcode ) = @_;
636 $sth->execute($frameworkcode,$kohafieldname);
637 if ( ( $tagfield, $tagsubfield ) = $sth->fetchrow ) {
638 if ( $record->field($tagfield) ) {
639 my $tag = $record->field($tagfield);
641 $tag->add_subfields( $tagsubfield, $value );
642 $record->delete_field($tag);
643 $record->add_fields($tag);
647 $record->add_fields( $tagfield, " ", " ", $tagsubfield => $value );
654 $XMLrecord = MARChtml2xml($rtags,$rsubfields,$rvalues,$indicator,$ind_tag);
656 transforms the parameters (coming from HTML form) into a MARC::File::XML
657 object. parameters with r are references to arrays
661 my ($tags,$subfields,$values,$indicator,$ind_tag) = @_;
663 my $xml= MARC::File::XML::header();
668 for (my $i=0;$i<=@$tags;$i++){
669 @$values[$i] =~ s/&/&/g;
670 @$values[$i] =~ s/</</g;
671 @$values[$i] =~ s/>/>/g;
672 @$values[$i] =~ s/"/"/g;
673 @$values[$i] =~ s/'/'/g;
675 if ((@$tags[$i] ne $prevtag)){
676 $j++ unless (@$tags[$i] eq "");
677 #warn "IND:".substr(@$indicator[$j],0,1).substr(@$indicator[$j],1,1)." ".@$tags[$i];
679 $xml.="</datafield>\n";
680 if ((@$tags[$i] > 10) && (@$values[$i] ne "")){
681 my $ind1 = substr(@$indicator[$j],0,1);
682 my $ind2 = substr(@$indicator[$j],1,1);
683 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
684 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
690 if (@$values[$i] ne "") {
692 if (@$tags[$i] eq "000") {
693 $xml.="<leader>@$values[$i]</leader>\n";
695 # rest of the fixed fields
696 } elsif (@$tags[$i] < 10) {
697 $xml.="<controlfield tag=\"@$tags[$i]\">@$values[$i]</controlfield>\n";
700 my $ind1 = substr(@$indicator[$j],0,1);
701 my $ind2 = substr(@$indicator[$j],1,1);
702 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
703 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
708 } else { # @$tags[$i] eq $prevtag
709 if (@$values[$i] eq "") {
713 my $ind1 = substr(@$indicator[$j],0,1);
714 my $ind2 = substr(@$indicator[$j],1,1);
715 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
718 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
721 $prevtag = @$tags[$i];
723 $xml.= MARC::File::XML::footer();
730 $hash = &MARCmarc2koha($dbh,$MARCRecord);
734 builds a hash with old-db datas from a MARC::Record
741 my ($dbh,$record,$frameworkcode) = @_;
742 my $sth=$dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
744 my $sth2=$dbh->prepare("SHOW COLUMNS from biblio");
747 while (($field)=$sth2->fetchrow) {
748 # warn "biblio.".$field;
749 $result=&MARCmarc2kohaOneField($sth,"biblio",$field,$record,$result,$frameworkcode);
751 $sth2=$dbh->prepare("SHOW COLUMNS from biblioitems");
753 while (($field)=$sth2->fetchrow) {
754 if ($field eq 'notes') { $field = 'bnotes'; }
755 # warn "biblioitems".$field;
756 $result=&MARCmarc2kohaOneField($sth,"biblioitems",$field,$record,$result,$frameworkcode);
758 $sth2=$dbh->prepare("SHOW COLUMNS from items");
760 while (($field)=$sth2->fetchrow) {
761 # warn "items".$field;
762 $result=&MARCmarc2kohaOneField($sth,"items",$field,$record,$result,$frameworkcode);
764 # additional authors : specific
765 $result = &MARCmarc2kohaOneField($sth,"bibliosubtitle","subtitle",$record,$result,$frameworkcode);
766 $result = &MARCmarc2kohaOneField($sth,"additionalauthors","additionalauthors",$record,$result,$frameworkcode);
767 # modify copyrightdate to keep only the 1st year found
768 my $temp = $result->{'copyrightdate'};
770 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
772 $result->{'copyrightdate'} = $1;
773 } else { # if no cYYYY, get the 1st date.
774 $temp =~ m/(\d\d\d\d)/;
775 $result->{'copyrightdate'} = $1;
778 # modify publicationyear to keep only the 1st year found
779 $temp = $result->{'publicationyear'};
780 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
782 $result->{'publicationyear'} = $1;
783 } else { # if no cYYYY, get the 1st date.
784 $temp =~ m/(\d\d\d\d)/;
785 $result->{'publicationyear'} = $1;
790 sub MARCmarc2kohaOneField {
792 # FIXME ? if a field has a repeatable subfield that is used in old-db, only the 1st will be retrieved...
793 my ( $sth, $kohatable, $kohafield, $record, $result,$frameworkcode ) = @_;
794 # warn "kohatable / $kohafield / $result / ";
798 ( $tagfield, $subfield ) = MARCfind_marc_from_kohafield("",$kohatable.".".$kohafield,$frameworkcode);
799 foreach my $field ( $record->field($tagfield) ) {
800 if ($field->tag()<10) {
801 if ($result->{$kohafield}) {
802 # Reverse array filled with elements from repeated subfields
803 # from first to last to avoid last to first concatenation of
804 # elements in Koha DB. -- thd.
805 $result->{$kohafield} .= " | ".reverse($field->data());
807 $result->{$kohafield} = $field->data();
810 if ( $field->subfields ) {
811 my @subfields = $field->subfields();
812 foreach my $subfieldcount ( 0 .. $#subfields ) {
813 if ($subfields[$subfieldcount][0] eq $subfield) {
814 if ( $result->{$kohafield} ) {
815 $result->{$kohafield} .= " | " . $subfields[$subfieldcount][1];
818 $result->{$kohafield} = $subfields[$subfieldcount][1];
825 # warn "OneField for $kohatable.$kohafield and $frameworkcode=> $tagfield, $subfield";
831 ($biblionumber,$biblioitemnumber) = NEWnewbibilio($dbh,$MARCRecord,$frameworkcode);
835 creates a biblio from a MARC::Record.
842 my ( $dbh,$record,$frameworkcode ) = @_;
844 my $biblioitemnumber;
845 my $olddata = MARCmarc2koha( $dbh, $record,$frameworkcode );
846 $olddata->{frameworkcode} = $frameworkcode;
847 $biblionumber = REALnewbiblio( $dbh, $olddata );
848 $olddata->{biblionumber} = $biblionumber;
849 # add biblionumber into the MARC record (it's the ID for zebra)
850 my ( $tagfield, $tagsubfield ) =
851 MARCfind_marc_from_kohafield( $dbh, "biblio.biblionumber",$frameworkcode );
855 $newfield = MARC::Field->new(
856 $tagfield, $biblionumber,
859 $newfield = MARC::Field->new(
860 $tagfield, '', '', "$tagsubfield" => $biblionumber,
863 # drop old field (just in case it already exist and create new one...
864 my $old_field = $record->field($tagfield);
865 $record->delete_field($old_field);
866 $record->add_fields($newfield);
868 #create the marc entry, that stores the rax marc record in Koha 3.0
869 $olddata->{marc} = $record->as_usmarc();
870 $olddata->{marcxml} = $record->as_xml();
871 # and create biblioitem, that's all folks !
872 $biblioitemnumber = REALnewbiblioitem( $dbh, $olddata );
874 # search subtiles, addiauthors and subjects
875 ( $tagfield, $tagsubfield ) =
876 MARCfind_marc_from_kohafield( $dbh, "additionalauthors.author",$frameworkcode );
877 my @addiauthfields = $record->field($tagfield);
878 foreach my $addiauthfield (@addiauthfields) {
879 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
880 foreach my $subfieldcount ( 0 .. $#addiauthsubfields ) {
881 REALmodaddauthor( $dbh, $biblionumber,
882 $addiauthsubfields[$subfieldcount] );
885 ( $tagfield, $tagsubfield ) =
886 MARCfind_marc_from_kohafield( $dbh, "bibliosubtitle.subtitle",$frameworkcode );
887 my @subtitlefields = $record->field($tagfield);
888 foreach my $subtitlefield (@subtitlefields) {
889 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
890 foreach my $subfieldcount ( 0 .. $#subtitlesubfields ) {
891 REALnewsubtitle( $dbh, $biblionumber,
892 $subtitlesubfields[$subfieldcount] );
895 ( $tagfield, $tagsubfield ) =
896 MARCfind_marc_from_kohafield( $dbh, "bibliosubject.subject",$frameworkcode );
897 my @subj = $record->field($tagfield);
899 foreach my $subject (@subj) {
900 my @subjsubfield = $subject->subfield($tagsubfield);
901 foreach my $subfieldcount ( 0 .. $#subjsubfield ) {
902 push @subjects, $subjsubfield[$subfieldcount];
905 REALmodsubject( $dbh, $biblionumber, 1, @subjects );
906 return ( $biblionumber, $biblioitemnumber );
909 =head2 NEWmodbilbioframework
911 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
915 modify the framework of a biblio
921 sub NEWmodbiblioframework {
922 my ($dbh,$biblionumber,$frameworkcode) =@_;
923 my $sth = $dbh->prepare("Update biblio SET frameworkcode=? WHERE biblionumber=?");
924 $sth->execute($frameworkcode,$biblionumber);
930 NEWmodbiblio($dbh,$MARCrecord,$biblionumber,$frameworkcode);
934 modify a biblio (MARC=ON)
941 my ($dbh,$record,$biblionumber,$frameworkcode) =@_;
942 $frameworkcode="" unless $frameworkcode;
943 # &MARCmodbiblio($dbh,$bibid,$record,$frameworkcode,0);
944 my $oldbiblio = MARCmarc2koha($dbh,$record,$frameworkcode);
946 $oldbiblio->{frameworkcode} = $frameworkcode;
947 #create the marc entry, that stores the rax marc record in Koha 3.0
948 $oldbiblio->{biblionumber} = $biblionumber unless $oldbiblio->{biblionumber};
949 $oldbiblio->{marc} = $record->as_usmarc();
950 $oldbiblio->{marcxml} = $record->as_xml();
951 warn "dans NEWmodbiblio $biblionumber = ".$oldbiblio->{biblionumber}." = ".$oldbiblio->{marcxml};
952 REALmodbiblio($dbh,$oldbiblio);
953 REALmodbiblioitem($dbh,$oldbiblio);
954 # now, modify addi authors, subject, addititles.
955 my ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"additionalauthors.author",$frameworkcode);
956 my @addiauthfields = $record->field($tagfield);
957 foreach my $addiauthfield (@addiauthfields) {
958 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
959 $dbh->do("delete from additionalauthors where biblionumber=$biblionumber");
960 foreach my $subfieldcount (0..$#addiauthsubfields) {
961 REALmodaddauthor($dbh,$biblionumber,$addiauthsubfields[$subfieldcount]);
964 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubtitle.subtitle",$frameworkcode);
965 my @subtitlefields = $record->field($tagfield);
966 foreach my $subtitlefield (@subtitlefields) {
967 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
968 # delete & create subtitle again because REALmodsubtitle can't handle new subtitles
970 $dbh->do("delete from bibliosubtitle where biblionumber=$biblionumber");
971 foreach my $subfieldcount (0..$#subtitlesubfields) {
972 foreach my $subtit(split /\||#/,$subtitlesubfields[$subfieldcount]) {
973 REALnewsubtitle($dbh,$biblionumber,$subtit);
977 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubject.subject",$frameworkcode);
978 my @subj = $record->field($tagfield);
980 foreach my $subject (@subj) {
981 my @subjsubfield = $subject->subfield($tagsubfield);
982 foreach my $subfieldcount (0..$#subjsubfield) {
983 push @subjects,$subjsubfield[$subfieldcount];
986 REALmodsubject($dbh,$biblionumber,1,@subjects);
990 =head2 NEWmodbilbioframework
992 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
1003 my ( $dbh, $bibid ) = @_;
1004 # my $biblio = &MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
1005 &REALdelbiblio( $dbh, $bibid );
1008 "select biblioitemnumber from biblioitems where biblionumber=?");
1009 $sth->execute($bibid);
1010 while ( my ($biblioitemnumber) = $sth->fetchrow ) {
1011 REALdelbiblioitem( $dbh, $biblioitemnumber );
1013 # &MARCdelbiblio( $dbh, $bibid, 0 );
1015 warn "heres the bibid $bibid";
1016 # my $record = C4::Search::get_record($bibid);
1017 my $record = C4::Search::get_xml_record($bibid);
1018 # z3950_extended_services('update',set_service_options('update'),$record);
1019 warn "heres the record to delete $bibid";
1020 my $Zconn = C4::Context->Zconn;
1021 my $p = $Zconn->package();
1022 $p->option(action => "recordDelete");
1023 $p->option(record => $record);
1026 # z3950_extended_services('update',set_service_options('update','recordDelete',$record));
1027 z3950_extended_services('commit');
1032 $itemnumber = NEWnewitem($dbh, $record, $biblionumber, $biblioitemnumber);
1036 creates an item from a MARC::Record
1043 my ( $dbh,$record,$biblionumber,$biblioitemnumber ) = @_;
1044 warn "here is the $biblioitemnumber";
1045 # add item in old-DB
1046 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
1047 my $item = &MARCmarc2koha( $dbh,$record,$frameworkcode );
1048 # needs old biblionumber and biblioitemnumber
1049 $item->{'biblionumber'} = $biblionumber;
1050 $item->{'biblioitemnumber'}=$biblioitemnumber;
1051 $item->{marc} = $record->as_usmarc();
1052 #warn $item->{marc};
1053 my ( $itemnumber, $error ) = &REALnewitems( $dbh, $item, $item->{barcode} );
1060 $itemnumber = NEWmoditem($dbh, $record, $biblionumber, $biblioitemnumber,$itemnumber);
1071 my ( $dbh, $record, $biblionumber, $biblioitemnumber, $itemnumber) = @_;
1073 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
1074 my $olditem = MARCmarc2koha( $dbh, $record,$frameworkcode );
1076 $olditem->{marc} = $record->as_usmarc();
1077 $olditem->{biblionumber} = $biblionumber;
1078 $olditem->{biblioitemnumber} = $biblioitemnumber;
1080 REALmoditem( $dbh, $olditem );
1086 $itemnumber = NEWdelitem($dbh, $biblionumber, $biblioitemnumber, $itemnumber);
1097 my ( $dbh, $bibid, $itemnumber ) = @_;
1098 &REALdelitem( $dbh, $itemnumber );
1099 # &MARCdelitem( $dbh, $bibid, $itemnumber );
1100 # we must now delete the item data from zebra
1104 =head2 REALnewbiblio
1106 $biblionumber = REALnewbiblio($dbh,$biblio);
1110 adds a record in biblio table. Datas are in the hash $biblio.
1117 my ( $dbh, $biblio ) = @_;
1119 $dbh->do('lock tables biblio WRITE');
1120 my $sth = $dbh->prepare("Select max(biblionumber) from biblio");
1122 my $data = $sth->fetchrow_arrayref;
1123 my $bibnum = $$data[0] + 1;
1126 if ( $biblio->{'seriestitle'} ) { $series = 1 }
1129 $dbh->prepare("insert into biblio set biblionumber=?, title=?, author=?, copyrightdate=?,
1130 serial=?, seriestitle=?, notes=?, abstract=?,
1134 $bibnum, $biblio->{'title'},
1135 $biblio->{'author'}, $biblio->{'copyrightdate'},
1136 $biblio->{'serial'}, $biblio->{'seriestitle'},
1137 $biblio->{'notes'}, $biblio->{'abstract'},
1138 $biblio->{'unititle'}
1142 $dbh->do('unlock tables');
1146 =head2 REALmodbiblio
1148 $biblionumber = REALmodbiblio($dbh,$biblio);
1152 modify a record in biblio table. Datas are in the hash $biblio.
1159 my ( $dbh, $biblio ) = @_;
1160 my $sth = $dbh->prepare("Update biblio set title=?, author=?, abstract=?, copyrightdate=?,
1161 seriestitle=?, serial=?, unititle=?, notes=?, frameworkcode=?
1162 where biblionumber = ?"
1165 $biblio->{'title'}, $biblio->{'author'},
1166 $biblio->{'abstract'}, $biblio->{'copyrightdate'},
1167 $biblio->{'seriestitle'}, $biblio->{'serial'},
1168 $biblio->{'unititle'}, $biblio->{'notes'},
1169 $biblio->{frameworkcode},
1170 $biblio->{'biblionumber'}
1173 return ( $biblio->{'biblionumber'} );
1176 =head2 REALmodsubtitle
1178 REALmodsubtitle($dbh,$bibnum,$subtitle);
1182 modify subtitles in bibliosubtitle table.
1188 sub REALmodsubtitle {
1189 my ( $dbh, $bibnum, $subtitle ) = @_;
1192 "update bibliosubtitle set subtitle = ? where biblionumber = ?");
1193 $sth->execute( $subtitle, $bibnum );
1197 =head2 REALmodaddauthor
1199 REALmodaddauthor($dbh,$bibnum,$author);
1203 adds or modify additional authors
1204 NOTE : Strange sub : seems to delete MANY and add only ONE author... maybe buggy ?
1210 sub REALmodaddauthor {
1211 my ( $dbh, $bibnum, @authors ) = @_;
1213 # my $dbh = C4Connect;
1215 $dbh->prepare("Delete from additionalauthors where biblionumber = ?");
1217 $sth->execute($bibnum);
1219 foreach my $author (@authors) {
1220 if ( $author ne '' ) {
1223 "Insert into additionalauthors set author = ?, biblionumber = ?"
1226 $sth->execute( $author, $bibnum );
1231 } # sub modaddauthor
1233 =head2 REALmodsubject
1235 $errors = REALmodsubject($dbh,$bibnum, $force, @subject);
1239 modify/adds subjects
1244 sub REALmodsubject {
1245 my ( $dbh, $bibnum, $force, @subject ) = @_;
1247 # my $dbh = C4Connect;
1248 my $count = @subject;
1250 for ( my $i = 0 ; $i < $count ; $i++ ) {
1251 $subject[$i] =~ s/^ //g;
1252 $subject[$i] =~ s/ $//g;
1255 "select * from catalogueentry where entrytype = 's' and catalogueentry = ?"
1257 $sth->execute( $subject[$i] );
1259 if ( my $data = $sth->fetchrow_hashref ) {
1262 if ( $force eq $subject[$i] || $force == 1 ) {
1264 # subject not in aut, chosen to force anway
1265 # so insert into cataloguentry so its in auth file
1268 "Insert into catalogueentry (entrytype,catalogueentry) values ('s',?)"
1271 $sth2->execute( $subject[$i] ) if ( $subject[$i] );
1276 "$subject[$i]\n does not exist in the subject authority file";
1279 "Select * from catalogueentry where entrytype = 's' and (catalogueentry like ? or catalogueentry like ? or catalogueentry like ?)"
1281 $sth2->execute( "$subject[$i] %", "% $subject[$i] %",
1283 while ( my $data = $sth2->fetchrow_hashref ) {
1284 $error .= "<br>$data->{'catalogueentry'}";
1293 $dbh->prepare("Delete from bibliosubject where biblionumber = ?");
1294 $sth->execute($bibnum);
1298 "Insert into bibliosubject (subject,biblionumber) values (?,?)");
1300 foreach $query (@subject) {
1301 $sth->execute( $query, $bibnum ) if ( $query && $bibnum );
1310 =head2 REALmodbiblioitem
1312 REALmodbiblioitem($dbh, $biblioitem);
1321 sub REALmodbiblioitem {
1322 my ( $dbh, $biblioitem ) = @_;
1325 my $sth = $dbh->prepare("update biblioitems set number=?,volume=?, volumedate=?, lccn=?,
1326 itemtype=?, url=?, isbn=?, issn=?,
1327 publishercode=?, publicationyear=?, classification=?, dewey=?,
1328 subclass=?, illus=?, pages=?, volumeddesc=?,
1329 notes=?, size=?, place=?, marc=?,
1331 where biblioitemnumber=?");
1332 $sth->execute( $biblioitem->{number}, $biblioitem->{volume}, $biblioitem->{volumedate}, $biblioitem->{lccn},
1333 $biblioitem->{itemtype}, $biblioitem->{url}, $biblioitem->{isbn}, $biblioitem->{issn},
1334 $biblioitem->{publishercode}, $biblioitem->{publicationyear}, $biblioitem->{classification}, $biblioitem->{dewey},
1335 $biblioitem->{subclass}, $biblioitem->{illus}, $biblioitem->{pages}, $biblioitem->{volumeddesc},
1336 $biblioitem->{bnotes}, $biblioitem->{size}, $biblioitem->{place}, $biblioitem->{marc},
1337 $biblioitem->{marcxml}, $biblioitem->{biblioitemnumber});
1339 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1341 z3950_extended_services('update',set_service_options('update'),$record);
1342 z3950_extended_services('commit');
1345 # warn "MOD : $biblioitem->{biblioitemnumber} = ".$biblioitem->{marc};
1348 =head2 REALnewbiblioitem
1350 REALnewbiblioitem($dbh,$biblioitem);
1354 adds a biblioitem ($biblioitem is a hash with the values)
1360 sub REALnewbiblioitem {
1361 my ( $dbh, $biblioitem ) = @_;
1363 $dbh->do("lock tables biblioitems WRITE, biblio WRITE, marc_subfield_structure READ");
1364 my $sth = $dbh->prepare("Select max(biblioitemnumber) from biblioitems");
1366 my $biblioitemnumber;
1369 $data = $sth->fetchrow_arrayref;
1370 $biblioitemnumber = $$data[0] + 1;
1372 # Insert biblioitemnumber in MARC record, we need it to manage items later...
1373 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblioitem->{biblionumber});
1374 my ($biblioitemnumberfield,$biblioitemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'biblioitems.biblioitemnumber',$frameworkcode);
1375 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1376 my $field=$record->field($biblioitemnumberfield);
1377 $field->update($biblioitemnumbersubfield => "$biblioitemnumber");
1378 $biblioitem->{marc} = $record->as_usmarc();
1379 $biblioitem->{marcxml} = $record->as_xml();
1381 $sth = $dbh->prepare( "insert into biblioitems set
1382 biblioitemnumber = ?, biblionumber = ?,
1383 volume = ?, number = ?,
1384 classification = ?, itemtype = ?,
1386 issn = ?, dewey = ?,
1387 subclass = ?, publicationyear = ?,
1388 publishercode = ?, volumedate = ?,
1389 volumeddesc = ?, illus = ?,
1390 pages = ?, notes = ?,
1392 marc = ?, place = ?,
1396 $biblioitemnumber, $biblioitem->{'biblionumber'},
1397 $biblioitem->{'volume'}, $biblioitem->{'number'},
1398 $biblioitem->{'classification'}, $biblioitem->{'itemtype'},
1399 $biblioitem->{'url'}, $biblioitem->{'isbn'},
1400 $biblioitem->{'issn'}, $biblioitem->{'dewey'},
1401 $biblioitem->{'subclass'}, $biblioitem->{'publicationyear'},
1402 $biblioitem->{'publishercode'}, $biblioitem->{'volumedate'},
1403 $biblioitem->{'volumeddesc'}, $biblioitem->{'illus'},
1404 $biblioitem->{'pages'}, $biblioitem->{'bnotes'},
1405 $biblioitem->{'size'}, $biblioitem->{'lccn'},
1406 $biblioitem->{'marc'}, $biblioitem->{'place'},
1407 $biblioitem->{marcxml},
1409 $dbh->do("unlock tables");
1410 z3950_extended_services('update',set_service_options('update'),$record);
1411 z3950_extended_services('commit');
1412 return ($biblioitemnumber);
1415 =head2 REALnewsubtitle
1417 REALnewsubtitle($dbh,$bibnum,$subtitle);
1421 create a new subtitle
1426 sub REALnewsubtitle {
1427 my ( $dbh, $bibnum, $subtitle ) = @_;
1430 "insert into bibliosubtitle set biblionumber = ?, subtitle = ?");
1431 $sth->execute( $bibnum, $subtitle ) if $subtitle;
1437 ($itemnumber,$errors)= REALnewitems($dbh,$item,$barcode);
1441 create a item. $item is a hash and $barcode the barcode.
1448 my ( $dbh, $item, $barcode ) = @_;
1450 # warn "OLDNEWITEMS";
1452 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE,marc_subfield_structure WRITE');
1453 my $sth = $dbh->prepare("Select max(itemnumber) from items");
1458 $data = $sth->fetchrow_hashref;
1459 $itemnumber = $data->{'max(itemnumber)'} + 1;
1461 # FIXME the "notforloan" field seems to be named "loan" in some places. workaround bugfix.
1462 if ( $item->{'loan'} ) {
1463 $item->{'notforloan'} = $item->{'loan'};
1465 # $item->{'biblioitemnumber'} = 1;
1466 # if dateaccessioned is provided, use it. Otherwise, set to NOW()
1467 if ( $item->{'dateaccessioned'} ) {
1468 $sth = $dbh->prepare( "Insert into items set
1469 itemnumber = ?, biblionumber = ?,
1470 multivolumepart = ?,
1471 biblioitemnumber = ?, barcode = ?,
1472 booksellerid = ?, dateaccessioned = ?,
1473 homebranch = ?, holdingbranch = ?,
1474 price = ?, replacementprice = ?,
1475 replacementpricedate = NOW(), datelastseen = NOW(),
1476 multivolume = ?, stack = ?,
1477 itemlost = ?, wthdrawn = ?,
1478 paidfor = ?, itemnotes = ?,
1479 itemcallnumber =?, notforloan = ?,
1484 $itemnumber, $item->{'biblionumber'},
1485 $item->{'multivolumepart'},
1486 $item->{'biblioitemnumber'},$item->{barcode},
1487 $item->{'booksellerid'}, $item->{'dateaccessioned'},
1488 $item->{'homebranch'}, $item->{'holdingbranch'},
1489 $item->{'price'}, $item->{'replacementprice'},
1490 $item->{multivolume}, $item->{stack},
1491 $item->{itemlost}, $item->{wthdrawn},
1492 $item->{paidfor}, $item->{'itemnotes'},
1493 $item->{'itemcallnumber'}, $item->{'notforloan'},
1496 if ( defined $sth->errstr ) {
1497 $error .= $sth->errstr;
1501 $sth = $dbh->prepare( "Insert into items set
1502 itemnumber = ?, biblionumber = ?,
1503 multivolumepart = ?,
1504 biblioitemnumber = ?, barcode = ?,
1505 booksellerid = ?, dateaccessioned = NOW(),
1506 homebranch = ?, holdingbranch = ?,
1507 price = ?, replacementprice = ?,
1508 replacementpricedate = NOW(), datelastseen = NOW(),
1509 multivolume = ?, stack = ?,
1510 itemlost = ?, wthdrawn = ?,
1511 paidfor = ?, itemnotes = ?,
1512 itemcallnumber =?, notforloan = ?,
1517 $itemnumber, $item->{'biblionumber'},
1518 $item->{'multivolumepart'},
1519 $item->{'biblioitemnumber'},$item->{barcode},
1520 $item->{'booksellerid'},
1521 $item->{'homebranch'}, $item->{'holdingbranch'},
1522 $item->{'price'}, $item->{'replacementprice'},
1523 $item->{multivolume}, $item->{stack},
1524 $item->{itemlost}, $item->{wthdrawn},
1525 $item->{paidfor}, $item->{'itemnotes'},
1526 $item->{'itemcallnumber'}, $item->{'notforloan'},
1529 if ( defined $sth->errstr ) {
1530 $error .= $sth->errstr;
1533 # item stored, now, deal with the marc part...
1534 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1535 where biblio.biblionumber=biblioitems.biblionumber and
1536 biblio.biblionumber=?");
1537 $sth->execute($item->{biblionumber});
1538 if ( defined $sth->errstr ) {
1539 $error .= $sth->errstr;
1541 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1542 warn "ERROR IN REALnewitem, MARC record not found FOR $item->{biblionumber} => $rawmarc <=" unless $rawmarc;
1543 my $record = MARC::File::USMARC::decode($rawmarc);
1544 # ok, we have the marc record, add item number to the item field (in {marc}, and add the field to the record)
1545 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1546 my $itemrecord = MARC::Record->new_from_usmarc($item->{marc});
1548 #warn $itemnumberfield;
1549 #warn $itemrecord->field($itemnumberfield);
1550 my $itemfield = $itemrecord->field($itemnumberfield);
1551 $itemfield->add_subfields($itemnumbersubfield => "$itemnumber");
1552 $record->insert_grouped_field($itemfield);
1553 # save the record into biblioitem
1554 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=?");
1555 $sth->execute($record->as_usmarc(),$record->as_xml(),$item->{biblionumber});
1556 if ( defined $sth->errstr ) {
1557 $error .= $sth->errstr;
1559 z3950_extended_services('update',set_service_options('update'),$record);
1560 z3950_extended_services('commit');
1561 $dbh->do('unlock tables');
1562 return ( $itemnumber, $error );
1565 =head2 REALmoditem($dbh,$item);
1576 my ( $dbh, $item ) = @_;
1577 $item->{'bibitemnum'} = 1;
1579 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE');
1580 $item->{'itemnum'} = $item->{'itemnumber'} unless $item->{'itemnum'};
1581 my $query = "update items set barcode=?,itemnotes=?,itemcallnumber=?,notforloan=?,location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1583 $item->{'barcode'}, $item->{'itemnotes'},
1584 $item->{'itemcallnumber'}, $item->{'notforloan'},
1585 $item->{'location'}, $item->{multivolumepart},
1586 $item->{multivolume}, $item->{stack},
1589 if ( $item->{'lost'} ne '' ) {
1590 $query = "update items set biblioitemnumber=?,barcode=?,itemnotes=?,homebranch=?,
1591 itemlost=?,wthdrawn=?,itemcallnumber=?,notforloan=?,
1592 location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1594 $item->{'bibitemnum'}, $item->{'barcode'},
1595 $item->{'itemnotes'}, $item->{'homebranch'},
1596 $item->{'lost'}, $item->{'wthdrawn'},
1597 $item->{'itemcallnumber'}, $item->{'notforloan'},
1598 $item->{'location'}, $item->{multivolumepart},
1599 $item->{multivolume}, $item->{stack},
1602 if ($item->{homebranch}) {
1603 $query.=",homebranch=?";
1604 push @bind, $item->{homebranch};
1606 if ($item->{holdingbranch}) {
1607 $query.=",holdingbranch=?";
1608 push @bind, $item->{holdingbranch};
1611 $query.=" where itemnumber=?";
1612 push @bind,$item->{'itemnum'};
1613 if ( $item->{'replacement'} ne '' ) {
1614 $query =~ s/ where/,replacementprice='$item->{'replacement'}' where/;
1616 my $sth = $dbh->prepare($query);
1617 $sth->execute(@bind);
1619 # item stored, now, deal with the marc part...
1620 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1621 where biblio.biblionumber=biblioitems.biblionumber and
1622 biblio.biblionumber=? and
1623 biblioitems.biblioitemnumber=?");
1624 $sth->execute($item->{biblionumber},$item->{biblioitemnumber});
1625 if ( defined $sth->errstr ) {
1626 $error .= $sth->errstr;
1628 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1629 # warn "ERROR IN REALmoditem, MARC record not found" unless $rawmarc;
1630 # my $record = MARC::File::USMARC::decode($rawmarc);
1631 my $record=C4::Search::get_record($item->{biblionumber});
1633 # ok, we have the marc record, find the previous item record for this itemnumber and delete it
1634 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1635 # prepare the new item record
1636 my $itemrecord = MARC::File::USMARC::decode($item->{marc});
1637 my $itemfield = $itemrecord->field($itemnumberfield);
1639 # $itemfield->add_subfields($itemnumbersubfield => '$itemnumber');
1640 # parse all fields fields from the complete record
1641 foreach ($record->field($itemnumberfield)) {
1642 # when the previous field is found, replace by the new one
1643 if ($_->subfield($itemnumbersubfield) == $item->{itemnum}) {
1644 $_->replace_with($itemfield);
1647 my $temptest = $_->subfield($itemnumbersubfield);
1648 warn " failed itemnum is $item->{itemnum} and value in record is $temptest";
1651 # $record->insert_grouped_field($itemfield);
1652 # save the record into biblioitem
1653 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=? and biblioitemnumber=?");
1654 $sth->execute($record->as_usmarc(),$record->as_xml(),$item->{biblionumber},$item->{biblioitemnumber});
1655 z3950_extended_services('update',set_service_options('update'),$record);
1656 z3950_extended_services('commit');
1657 if ( defined $sth->errstr ) {
1658 $error .= $sth->errstr;
1660 $dbh->do('unlock tables');
1664 =head2 REALdelitem($dbh,$itemnum);
1675 my ( $dbh, $itemnum ) = @_;
1677 # my $dbh=C4Connect;
1678 my $sth = $dbh->prepare("select * from items where itemnumber=?");
1679 $sth->execute($itemnum);
1680 my $data = $sth->fetchrow_hashref;
1682 my $query = "Insert into deleteditems set ";
1684 foreach my $temp ( keys %$data ) {
1685 $query .= "$temp = ?,";
1686 push ( @bind, $data->{$temp} );
1691 $sth = $dbh->prepare($query);
1692 $sth->execute(@bind);
1694 $sth = $dbh->prepare("Delete from items where itemnumber=?");
1695 $sth->execute($itemnum);
1701 =head2 REALdelbiblioitem($dbh,$biblioitemnumber);
1705 deletes a biblioitem
1706 NOTE : not standard sub name. Should be REALdelbiblioitem()
1712 sub REALdelbiblioitem {
1713 my ( $dbh, $biblioitemnumber ) = @_;
1715 # my $dbh = C4Connect;
1716 my $sth = $dbh->prepare( "Select * from biblioitems
1717 where biblioitemnumber = ?"
1721 $sth->execute($biblioitemnumber);
1723 if ( $results = $sth->fetchrow_hashref ) {
1727 "Insert into deletedbiblioitems (biblioitemnumber, biblionumber, volume, number, classification, itemtype,
1728 isbn, issn ,dewey ,subclass ,publicationyear ,publishercode ,volumedate ,volumeddesc ,timestamp ,illus ,
1729 pages ,notes ,size ,url ,lccn ) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
1733 $results->{biblioitemnumber}, $results->{biblionumber},
1734 $results->{volume}, $results->{number},
1735 $results->{classification}, $results->{itemtype},
1736 $results->{isbn}, $results->{issn},
1737 $results->{dewey}, $results->{subclass},
1738 $results->{publicationyear}, $results->{publishercode},
1739 $results->{volumedate}, $results->{volumeddesc},
1740 $results->{timestamp}, $results->{illus},
1741 $results->{pages}, $results->{notes},
1742 $results->{size}, $results->{url},
1746 $dbh->prepare("Delete from biblioitems where biblioitemnumber = ?");
1747 $sth2->execute($biblioitemnumber);
1752 # Now delete all the items attached to the biblioitem
1753 $sth = $dbh->prepare("Select * from items where biblioitemnumber = ?");
1754 $sth->execute($biblioitemnumber);
1756 while ( my $data = $sth->fetchrow_hashref ) {
1757 my $query = "Insert into deleteditems set ";
1759 foreach my $temp ( keys %$data ) {
1760 $query .= "$temp = ?,";
1761 push ( @bind, $data->{$temp} );
1764 my $sth2 = $dbh->prepare($query);
1765 $sth2->execute(@bind);
1768 $sth = $dbh->prepare("Delete from items where biblioitemnumber = ?");
1769 $sth->execute($biblioitemnumber);
1773 } # sub deletebiblioitem
1775 =head2 REALdelbiblio($dbh,$biblio);
1786 my ( $dbh, $biblio ) = @_;
1787 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
1788 $sth->execute($biblio);
1789 if ( my $data = $sth->fetchrow_hashref ) {
1791 my $query = "Insert into deletedbiblio set ";
1793 foreach my $temp ( keys %$data ) {
1794 $query .= "$temp = ?,";
1795 push ( @bind, $data->{$temp} );
1798 #replacing the last , by ",?)"
1800 $sth = $dbh->prepare($query);
1801 $sth->execute(@bind);
1803 $sth = $dbh->prepare("Delete from biblio where biblionumber=?");
1804 $sth->execute($biblio);
1812 $number = itemcount($biblio);
1816 returns the number of items attached to a biblio
1824 my $dbh = C4::Context->dbh;
1827 my $sth = $dbh->prepare("Select count(*) from items where biblionumber=?");
1828 $sth->execute($biblio);
1829 my $data = $sth->fetchrow_hashref;
1831 return ( $data->{'count(*)'} );
1836 $biblionumber = newbiblio($biblio);
1840 create a biblio. The parameter is a hash
1848 my $dbh = C4::Context->dbh;
1849 my $bibnum = REALnewbiblio( $dbh, $biblio );
1850 # finds new (MARC bibid
1851 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1852 # my $record = &MARCkoha2marcBiblio( $dbh, $bibnum );
1853 # MARCaddbiblio( $dbh, $record, $bibnum,'' );
1859 $biblionumber = &modbiblio($biblio);
1863 Update a biblio record.
1865 C<$biblio> is a reference-to-hash whose keys are the fields in the
1866 biblio table in the Koha database. All fields must be present, not
1867 just the ones you wish to change.
1869 C<&modbiblio> updates the record defined by
1870 C<$biblio-E<gt>{biblionumber}> with the values in C<$biblio>.
1872 C<&modbiblio> returns C<$biblio-E<gt>{biblionumber}> whether it was
1881 my $dbh = C4::Context->dbh;
1882 my $biblionumber=REALmodbiblio($dbh,$biblio);
1883 my $record = MARCkoha2marcBiblio($dbh,$biblionumber,$biblionumber);
1884 # finds new (MARC bibid
1885 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$biblionumber);
1886 MARCmodbiblio($dbh,$bibid,$record,"",0);
1887 return($biblionumber);
1890 =head2 &modsubtitle($biblionumber, $subtitle);
1894 Sets the subtitle of a book.
1896 C<$biblionumber> is the biblionumber of the book to modify.
1898 C<$subtitle> is the new subtitle.
1905 my ( $bibnum, $subtitle ) = @_;
1906 my $dbh = C4::Context->dbh;
1907 &REALmodsubtitle( $dbh, $bibnum, $subtitle );
1910 =head2 &modaddauthor($biblionumber, $author);
1914 Replaces all additional authors for the book with biblio number
1915 C<$biblionumber> with C<$author>. If C<$author> is the empty string,
1916 C<&modaddauthor> deletes all additional authors.
1923 my ( $bibnum, @authors ) = @_;
1924 my $dbh = C4::Context->dbh;
1925 &REALmodaddauthor( $dbh, $bibnum, @authors );
1926 } # sub modaddauthor
1930 $error = &modsubject($biblionumber, $force, @subjects);
1934 $force - a subject to force
1935 $error - Error message, or undef if successful.
1942 my ( $bibnum, $force, @subject ) = @_;
1943 my $dbh = C4::Context->dbh;
1944 my $error = &REALmodsubject( $dbh, $bibnum, $force, @subject );
1946 # When MARC is off, ensures that the MARC biblio table gets updated with new
1947 # subjects, of course, it deletes the biblio in marc, and then recreates.
1948 # This check is to ensure that no MARC data exists to lose.
1949 # if (C4::Context->preference("MARC") eq '0'){
1950 # warn "in modSUBJECT";
1951 # my $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibnum);
1952 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1953 # &MARCmodbiblio($dbh,$bibid, $MARCRecord);
1959 =head2 modbibitem($dbh, $biblioitem);
1963 modify a biblioitem. The parameter is a hash
1970 my ($dbh, $biblioitem) = @_;
1971 #my $dbh = C4::Context->dbh;
1972 &REALmodbiblioitem( $dbh, $biblioitem );
1975 =head2 newbiblioitem
1977 $biblioitemnumber = newbiblioitem($biblioitem)
1981 create a biblioitem, the parameter is a hash
1988 my ($dbh, $biblioitem) = @_;
1989 #my $dbh = C4::Context->dbh;
1990 # add biblio information to the hash
1991 my $MARCbiblio = MARCkoha2marcBiblio( $dbh, $biblioitem );
1992 $biblioitem->{marc} = $MARCbiblio->as_usmarc();
1993 my $bibitemnum = &REALnewbiblioitem( $dbh, $biblioitem );
1994 return ($bibitemnum);
1997 =head2 newsubtitle($biblionumber,$subtitle);
2001 insert a subtitle for $biblionumber biblio
2009 my ( $bibnum, $subtitle ) = @_;
2010 my $dbh = C4::Context->dbh;
2011 &REALnewsubtitle( $dbh, $bibnum, $subtitle );
2016 $errors = newitems($dbh, $item, @barcodes);
2020 insert items ($item is a hash)
2028 my ( $dbh, $item, @barcodes ) = @_;
2029 #my $dbh = C4::Context->dbh;
2033 foreach my $barcode (@barcodes) {
2034 # add items, one by one for each barcode.
2036 $oneitem->{barcode}= $barcode;
2037 my $MARCitem = &MARCkoha2marcItem( $dbh, $oneitem);
2038 $oneitem->{marc} = $MARCitem->as_usmarc;
2039 ( $itemnumber, $error ) = &REALnewitems( $dbh, $oneitem);
2040 # $errors .= $error;
2041 # &MARCadditem( $dbh, $MARCitem, $item->{biblionumber} );
2046 =head2 moditem($dbh,$item);
2050 modify an item ($item is a hash with all item informations)
2058 my ($dbh, $item) = @_;
2059 #my $dbh = C4::Context->dbh;
2060 &REALmoditem( $dbh, $item );
2062 &MARCkoha2marcItem( $dbh, $item->{'biblionumber'}, $item->{'itemnum'} );
2064 &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $item->{biblionumber} );
2065 &MARCmoditem( $dbh, $MARCitem, $bibid, $item->{itemnum}, 0 );
2070 $error = checkitems($count,@barcodes);
2074 check for each @barcode entry that the barcode is not a duplicate
2081 my ( $count, @barcodes ) = @_;
2082 my $dbh = C4::Context->dbh;
2084 my $sth = $dbh->prepare("Select * from items where barcode=?");
2085 for ( my $i = 0 ; $i < $count ; $i++ ) {
2086 $barcodes[$i] = uc $barcodes[$i];
2087 $sth->execute( $barcodes[$i] );
2088 if ( my $data = $sth->fetchrow_hashref ) {
2089 $error .= " Duplicate Barcode: $barcodes[$i]";
2096 =head2 delitem($itemnum);
2100 delete item $itemnum being the item number to delete
2108 my $dbh = C4::Context->dbh;
2109 &REALdelitem( $dbh, $itemnum );
2112 =head2 deletebiblioitem($biblioitemnumber);
2116 delete the biblioitem $biblioitemnumber
2122 sub deletebiblioitem {
2123 my ($biblioitemnumber) = @_;
2124 my $dbh = C4::Context->dbh;
2125 &REALdelbiblioitem( $dbh, $biblioitemnumber );
2126 } # sub deletebiblioitem
2128 =head2 delbiblio($biblionumber)
2132 delete biblio $biblionumber
2140 my $dbh = C4::Context->dbh;
2141 &REALdelbiblio( $dbh, $biblio );
2142 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $biblio );
2143 &MARCdelbiblio( $dbh, $bibid, 0 );
2148 ($count,@results) = getbiblio($biblionumber);
2152 return an array with hash of biblios.
2154 FIXME : biblionumber being the primary key, this sub will always return only 1 result, API should be modified...
2161 my ($biblionumber) = @_;
2162 my $dbh = C4::Context->dbh;
2163 my $sth = $dbh->prepare("Select * from biblio where biblionumber = ?");
2165 # || die "Cannot prepare $query\n" . $dbh->errstr;
2169 $sth->execute($biblionumber);
2171 # || die "Cannot execute $query\n" . $sth->errstr;
2172 while ( my $data = $sth->fetchrow_hashref ) {
2173 $results[$count] = $data;
2178 return ( $count, @results );
2183 $data = &bibdata($biblionumber, $type);
2185 Returns information about the book with the given biblionumber.
2187 C<$type> is ignored.
2189 C<&bibdata> returns a reference-to-hash. The keys are the fields in
2190 the C<biblio>, C<biblioitems>, and C<bibliosubtitle> tables in the
2193 In addition, C<$data-E<gt>{subject}> is the list of the book's
2194 subjects, separated by C<" , "> (space, comma, space).
2196 If there are multiple biblioitems with the given biblionumber, only
2197 the first one is considered.
2202 my ($bibnum, $type) = @_;
2203 my $dbh = C4::Context->dbh;
2204 my $sth = $dbh->prepare("Select *, biblioitems.notes AS bnotes, biblio.notes
2206 left join biblioitems on biblioitems.biblionumber = biblio.biblionumber
2207 left join bibliosubtitle on
2208 biblio.biblionumber = bibliosubtitle.biblionumber
2209 left join itemtypes on biblioitems.itemtype=itemtypes.itemtype
2210 where biblio.biblionumber = ?
2212 $sth->execute($bibnum);
2214 $data = $sth->fetchrow_hashref;
2216 # handle management of repeated subtitle
2217 $sth = $dbh->prepare("Select * from bibliosubtitle where biblionumber = ?");
2218 $sth->execute($bibnum);
2220 while (my $dat = $sth->fetchrow_hashref){
2222 $line{subtitle} = $dat->{subtitle};
2223 push @subtitles, \%line;
2225 $data->{subtitles} = \@subtitles;
2227 $sth = $dbh->prepare("Select * from bibliosubject where biblionumber = ?");
2228 $sth->execute($bibnum);
2230 while (my $dat = $sth->fetchrow_hashref){
2232 $line{subject} = $dat->{'subject'};
2233 push @subjects, \%line;
2235 $data->{subjects} = \@subjects;
2237 $sth = $dbh->prepare("Select * from additionalauthors where biblionumber = ?");
2238 $sth->execute($bibnum);
2239 while (my $dat = $sth->fetchrow_hashref){
2240 $data->{'additionalauthors'} .= "$dat->{'author'} - ";
2242 chop $data->{'additionalauthors'};
2243 chop $data->{'additionalauthors'};
2244 chop $data->{'additionalauthors'};
2249 =head2 getbiblioitem
2251 ($count,@results) = getbiblioitem($biblioitemnumber);
2255 return an array with hash of biblioitemss.
2257 FIXME : biblioitemnumber being unique, this sub will always return only 1 result, API should be modified...
2264 my ($biblioitemnum) = @_;
2265 my $dbh = C4::Context->dbh;
2266 my $sth = $dbh->prepare( "Select * from biblioitems where
2267 biblioitemnumber = ?"
2272 $sth->execute($biblioitemnum);
2274 while ( my $data = $sth->fetchrow_hashref ) {
2275 $results[$count] = $data;
2280 return ( $count, @results );
2281 } # sub getbiblioitem
2283 =head2 getbiblioitembybiblionumber
2285 ($count,@results) = getbiblioitembybiblionumber($biblionumber);
2289 return an array with hash of biblioitems for the given biblionumber.
2295 sub getbiblioitembybiblionumber {
2296 my ($biblionumber) = @_;
2297 my $dbh = C4::Context->dbh;
2298 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?");
2302 $sth->execute($biblionumber);
2304 while ( my $data = $sth->fetchrow_hashref ) {
2305 $results[$count] = $data;
2310 return ( $count, @results );
2313 =head2 getitemsbybiblioitem
2315 ($count,@results) = getitemsbybiblioitem($biblionumber);
2319 returns an array with hash of items
2325 sub getitemsbybiblioitem {
2326 my ($biblioitemnum) = @_;
2327 my $dbh = C4::Context->dbh;
2328 my $sth = $dbh->prepare( "Select * from items, biblio where
2329 biblio.biblionumber = items.biblionumber and biblioitemnumber
2333 # || die "Cannot prepare $query\n" . $dbh->errstr;
2337 $sth->execute($biblioitemnum);
2339 # || die "Cannot execute $query\n" . $sth->errstr;
2340 while ( my $data = $sth->fetchrow_hashref ) {
2341 $results[$count] = $data;
2346 return ( $count, @results );
2347 } # sub getitemsbybiblioitem
2351 @results = &ItemInfo($env, $biblionumber, $type);
2353 Returns information about books with the given biblionumber.
2355 C<$type> may be either C<intra> or anything else. If it is not set to
2356 C<intra>, then the search will exclude lost, very overdue, and
2361 C<&ItemInfo> returns a list of references-to-hash. Each element
2362 contains a number of keys. Most of them are table items from the
2363 C<biblio>, C<biblioitems>, C<items>, and C<itemtypes> tables in the
2364 Koha database. Other keys include:
2368 =item C<$data-E<gt>{branchname}>
2370 The name (not the code) of the branch to which the book belongs.
2372 =item C<$data-E<gt>{datelastseen}>
2374 This is simply C<items.datelastseen>, except that while the date is
2375 stored in YYYY-MM-DD format in the database, here it is converted to
2376 DD/MM/YYYY format. A NULL date is returned as C<//>.
2378 =item C<$data-E<gt>{datedue}>
2380 =item C<$data-E<gt>{class}>
2382 This is the concatenation of C<biblioitems.classification>, the book's
2383 Dewey code, and C<biblioitems.subclass>.
2385 =item C<$data-E<gt>{ocount}>
2387 I think this is the number of copies of the book available.
2389 =item C<$data-E<gt>{order}>
2391 If this is set, it is set to C<One Order>.
2398 my ($env,$biblionumber,$type) = @_;
2399 my $dbh = C4::Context->dbh;
2400 my $query = "SELECT *,items.notforloan as itemnotforloan FROM items, biblio, biblioitems
2401 left join itemtypes on biblioitems.itemtype = itemtypes.itemtype
2402 WHERE items.biblionumber = ?
2403 AND biblioitems.biblioitemnumber = items.biblioitemnumber
2404 AND biblio.biblionumber = items.biblionumber";
2405 $query .= " order by items.dateaccessioned desc";
2406 my $sth=$dbh->prepare($query);
2407 $sth->execute($biblionumber);
2410 while (my $data=$sth->fetchrow_hashref){
2412 my $isth=$dbh->prepare("Select issues.*,borrowers.cardnumber from issues,borrowers where itemnumber = ? and returndate is null and issues.borrowernumber=borrowers.borrowernumber");
2413 $isth->execute($data->{'itemnumber'});
2414 if (my $idata=$isth->fetchrow_hashref){
2415 $data->{borrowernumber} = $idata->{borrowernumber};
2416 $data->{cardnumber} = $idata->{cardnumber};
2417 $datedue = format_date($idata->{'date_due'});
2419 if ($datedue eq ''){
2420 my ($restype,$reserves)=C4::Reserves2::CheckReserves($data->{'itemnumber'});
2426 #get branch information.....
2427 my $bsth=$dbh->prepare("SELECT * FROM branches WHERE branchcode = ?");
2428 $bsth->execute($data->{'holdingbranch'});
2429 if (my $bdata=$bsth->fetchrow_hashref){
2430 $data->{'branchname'} = $bdata->{'branchname'};
2432 my $date=format_date($data->{'datelastseen'});
2433 $data->{'datelastseen'}=$date;
2434 $data->{'datedue'}=$datedue;
2435 # get notforloan complete status if applicable
2436 my $sthnflstatus = $dbh->prepare('select authorised_value from marc_subfield_structure where kohafield="items.notforloan"');
2437 $sthnflstatus->execute;
2438 my ($authorised_valuecode) = $sthnflstatus->fetchrow;
2439 if ($authorised_valuecode) {
2440 $sthnflstatus = $dbh->prepare("select lib from authorised_values where category=? and authorised_value=?");
2441 $sthnflstatus->execute($authorised_valuecode,$data->{itemnotforloan});
2442 my ($lib) = $sthnflstatus->fetchrow;
2443 $data->{notforloan} = $lib;
2454 ($count, @results) = &bibitems($biblionumber);
2456 Given the biblionumber for a book, C<&bibitems> looks up that book's
2457 biblioitems (different publications of the same book, the audio book
2458 and film versions, etc.).
2460 C<$count> is the number of elements in C<@results>.
2462 C<@results> is an array of references-to-hash; the keys are the fields
2463 of the C<biblioitems> and C<itemtypes> tables of the Koha database. In
2464 addition, C<itemlost> indicates the availability of the item: if it is
2465 "2", then all copies of the item are long overdue; if it is "1", then
2466 all copies are lost; otherwise, there is at least one copy available.
2472 my $dbh = C4::Context->dbh;
2473 my $sth = $dbh->prepare("SELECT biblioitems.*,
2475 MIN(items.itemlost) as itemlost,
2476 MIN(items.dateaccessioned) as dateaccessioned
2477 FROM biblioitems, itemtypes, items
2478 WHERE biblioitems.biblionumber = ?
2479 AND biblioitems.itemtype = itemtypes.itemtype
2480 AND biblioitems.biblioitemnumber = items.biblioitemnumber
2481 GROUP BY items.biblioitemnumber");
2484 $sth->execute($bibnum);
2485 while (my $data = $sth->fetchrow_hashref) {
2486 $results[$count] = $data;
2490 return($count, @results);
2496 $itemdata = &bibitemdata($biblioitemnumber);
2498 Looks up the biblioitem with the given biblioitemnumber. Returns a
2499 reference-to-hash. The keys are the fields from the C<biblio>,
2500 C<biblioitems>, and C<itemtypes> tables in the Koha database, except
2501 that C<biblioitems.notes> is given as C<$itemdata-E<gt>{bnotes}>.
2507 my $dbh = C4::Context->dbh;
2508 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");
2511 $sth->execute($bibitem);
2513 $data = $sth->fetchrow_hashref;
2520 =head2 getbibliofromitemnumber
2522 $item = &getbibliofromitemnumber($env, $dbh, $itemnumber);
2524 Looks up the item with the given itemnumber.
2526 C<$env> and C<$dbh> are ignored.
2528 C<&itemnodata> returns a reference-to-hash whose keys are the fields
2529 from the C<biblio>, C<biblioitems>, and C<items> tables in the Koha
2534 sub getbibliofromitemnumber {
2535 my ($env,$dbh,$itemnumber) = @_;
2536 $dbh = C4::Context->dbh;
2537 my $sth=$dbh->prepare("Select * from biblio,items,biblioitems
2538 where items.itemnumber = ?
2539 and biblio.biblionumber = items.biblionumber
2540 and biblioitems.biblioitemnumber = items.biblioitemnumber");
2542 $sth->execute($itemnumber);
2543 my $data=$sth->fetchrow_hashref;
2550 @barcodes = &barcodes($biblioitemnumber);
2552 Given a biblioitemnumber, looks up the corresponding items.
2554 Returns an array of references-to-hash; the keys are C<barcode> and
2557 The returned items include very overdue items, but not lost ones.
2562 #called from request.pl
2563 my ($biblioitemnumber)=@_;
2564 my $dbh = C4::Context->dbh;
2565 my $sth=$dbh->prepare("SELECT barcode, itemlost, holdingbranch FROM items
2566 WHERE biblioitemnumber = ?
2567 AND (wthdrawn <> 1 OR wthdrawn IS NULL)");
2568 $sth->execute($biblioitemnumber);
2571 while (my $data=$sth->fetchrow_hashref){
2572 $barcodes[$i]=$data;
2582 $item = &itemdata($barcode);
2584 Looks up the item with the given barcode, and returns a
2585 reference-to-hash containing information about that item. The keys of
2586 the hash are the fields from the C<items> and C<biblioitems> tables in
2591 sub get_item_from_barcode {
2593 my $dbh = C4::Context->dbh;
2594 my $sth=$dbh->prepare("Select * from items,biblioitems where barcode=?
2595 and items.biblioitemnumber=biblioitems.biblioitemnumber");
2596 $sth->execute($barcode);
2597 my $data=$sth->fetchrow_hashref;
2605 @issues = &itemissues($biblioitemnumber, $biblio);
2607 Looks up information about who has borrowed the bookZ<>(s) with the
2608 given biblioitemnumber.
2610 C<$biblio> is ignored.
2612 C<&itemissues> returns an array of references-to-hash. The keys
2613 include the fields from the C<items> table in the Koha database.
2614 Additional keys include:
2620 If the item is currently on loan, this gives the due date.
2622 If the item is not on loan, then this is either "Available" or
2623 "Cancelled", if the item has been withdrawn.
2627 If the item is currently on loan, this gives the card number of the
2628 patron who currently has the item.
2630 =item C<timestamp0>, C<timestamp1>, C<timestamp2>
2632 These give the timestamp for the last three times the item was
2635 =item C<card0>, C<card1>, C<card2>
2637 The card number of the last three patrons who borrowed this item.
2639 =item C<borrower0>, C<borrower1>, C<borrower2>
2641 The borrower number of the last three patrons who borrowed this item.
2648 my ($bibitem, $biblio)=@_;
2649 my $dbh = C4::Context->dbh;
2650 # FIXME - If this function die()s, the script will abort, and the
2651 # user won't get anything; depending on how far the script has
2652 # gotten, the user might get a blank page. It would be much better
2653 # to at least print an error message. The easiest way to do this
2654 # is to set $SIG{__DIE__}.
2655 my $sth = $dbh->prepare("Select * from items where
2656 items.biblioitemnumber = ?")
2657 || die $dbh->errstr;
2661 $sth->execute($bibitem)
2662 || die $sth->errstr;
2664 while (my $data = $sth->fetchrow_hashref) {
2665 # Find out who currently has this item.
2666 # FIXME - Wouldn't it be better to do this as a left join of
2667 # some sort? Currently, this code assumes that if
2668 # fetchrow_hashref() fails, then the book is on the shelf.
2669 # fetchrow_hashref() can fail for any number of reasons (e.g.,
2670 # database server crash), not just because no items match the
2672 my $sth2 = $dbh->prepare("select * from issues,borrowers
2673 where itemnumber = ?
2674 and returndate is NULL
2675 and issues.borrowernumber = borrowers.borrowernumber");
2677 $sth2->execute($data->{'itemnumber'});
2678 if (my $data2 = $sth2->fetchrow_hashref) {
2679 $data->{'date_due'} = $data2->{'date_due'};
2680 $data->{'card'} = $data2->{'cardnumber'};
2681 $data->{'borrower'} = $data2->{'borrowernumber'};
2683 if ($data->{'wthdrawn'} eq '1') {
2684 $data->{'date_due'} = 'Cancelled';
2686 $data->{'date_due'} = 'Available';
2692 # Find the last 3 people who borrowed this item.
2693 $sth2 = $dbh->prepare("select * from issues, borrowers
2694 where itemnumber = ?
2695 and issues.borrowernumber = borrowers.borrowernumber
2696 and returndate is not NULL
2697 order by returndate desc,timestamp desc") || die $dbh->errstr;
2698 $sth2->execute($data->{'itemnumber'}) || die $sth2->errstr;
2699 for (my $i2 = 0; $i2 < 2; $i2++) { # FIXME : error if there is less than 3 pple borrowing this item
2700 if (my $data2 = $sth2->fetchrow_hashref) {
2701 $data->{"timestamp$i2"} = $data2->{'timestamp'};
2702 $data->{"card$i2"} = $data2->{'cardnumber'};
2703 $data->{"borrower$i2"} = $data2->{'borrowernumber'};
2708 $results[$i] = $data;
2718 ($count, $subjects) = &getsubject($biblionumber);
2720 Looks up the subjects of the book with the given biblionumber. Returns
2721 a two-element list. C<$subjects> is a reference-to-array, where each
2722 element is a subject of the book, and C<$count> is the number of
2723 elements in C<$subjects>.
2729 my $dbh = C4::Context->dbh;
2730 my $sth=$dbh->prepare("Select * from bibliosubject where biblionumber=?");
2731 $sth->execute($bibnum);
2734 while (my $data=$sth->fetchrow_hashref){
2739 return($i,\@results);
2744 ($count, $authors) = &getaddauthor($biblionumber);
2746 Looks up the additional authors for the book with the given
2749 Returns a two-element list. C<$authors> is a reference-to-array, where
2750 each element is an additional author, and C<$count> is the number of
2751 elements in C<$authors>.
2757 my $dbh = C4::Context->dbh;
2758 my $sth=$dbh->prepare("Select * from additionalauthors where biblionumber=?");
2759 $sth->execute($bibnum);
2762 while (my $data=$sth->fetchrow_hashref){
2767 return($i,\@results);
2773 ($count, $subtitles) = &getsubtitle($biblionumber);
2775 Looks up the subtitles for the book with the given biblionumber.
2777 Returns a two-element list. C<$subtitles> is a reference-to-array,
2778 where each element is a subtitle, and C<$count> is the number of
2779 elements in C<$subtitles>.
2785 my $dbh = C4::Context->dbh;
2786 my $sth=$dbh->prepare("Select * from bibliosubtitle where biblionumber=?");
2787 $sth->execute($bibnum);
2790 while (my $data=$sth->fetchrow_hashref){
2795 return($i,\@results);
2801 ($count, @websites) = &getwebsites($biblionumber);
2803 Looks up the web sites pertaining to the book with the given
2806 C<$count> is the number of elements in C<@websites>.
2808 C<@websites> is an array of references-to-hash; the keys are the
2809 fields from the C<websites> table in the Koha database.
2812 #FIXME : could maybe be deleted. Otherwise, would be better in a Websites.pm package
2813 #(with add / modify / delete subs)
2816 my ($biblionumber) = @_;
2817 my $dbh = C4::Context->dbh;
2818 my $sth = $dbh->prepare("Select * from websites where biblionumber = ?");
2822 $sth->execute($biblionumber);
2823 while (my $data = $sth->fetchrow_hashref) {
2824 # FIXME - The URL scheme shouldn't be stripped off, at least
2825 # not here, since it's part of the URL, and will be useful in
2826 # constructing a link to the site. If you don't want the user
2827 # to see the "http://" part, strip that off when building the
2829 $data->{'url'} =~ s/^http:\/\///; # FIXME - Leaning toothpick
2831 $results[$count] = $data;
2836 return($count, @results);
2839 =head2 getwebbiblioitems
2841 ($count, @results) = &getwebbiblioitems($biblionumber);
2843 Given a book's biblionumber, looks up the web versions of the book
2844 (biblioitems with itemtype C<WEB>).
2846 C<$count> is the number of items in C<@results>. C<@results> is an
2847 array of references-to-hash; the keys are the items from the
2848 C<biblioitems> table of the Koha database.
2852 sub getwebbiblioitems {
2853 my ($biblionumber) = @_;
2854 my $dbh = C4::Context->dbh;
2855 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?
2856 and itemtype = 'WEB'");
2860 $sth->execute($biblionumber);
2861 while (my $data = $sth->fetchrow_hashref) {
2862 $data->{'url'} =~ s/^http:\/\///;
2863 $results[$count] = $data;
2868 return($count, @results);
2869 } # sub getwebbiblioitems
2872 my $NSB = '\x88'; # NSB : begin Non Sorting Block
2873 my $NSE = '\x89'; # NSE : Non Sorting Block end
2874 # handles non sorting blocks
2878 s/[ ]{0,1}$NSE/) /gm;
2885 my $dbh = C4::Context->dbh;
2886 my $result = MARCmarc2koha($dbh,$record,'');
2888 my ($biblionumber,$bibid,$title);
2889 # search duplicate on ISBN, easy and fast...
2890 if ($result->{isbn}) {
2891 $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=?");
2892 $sth->execute($result->{'isbn'});
2893 ($biblionumber,$bibid,$title) = $sth->fetchrow;
2894 return $biblionumber,$bibid,$title if ($biblionumber);
2896 # a more complex search : build a request for SearchMarc::catalogsearch()
2897 my (@tags, @and_or, @excluding, @operator, @value, $offset,$length);
2898 # search on biblio.title
2899 my ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.title","");
2900 if ($record->field($tag)) {
2901 if ($record->field($tag)->subfields($subfield)) {
2902 push @tags, "'".$tag.$subfield."'";
2903 push @and_or, "and";
2904 push @excluding, "";
2905 push @operator, "contains";
2906 push @value, $record->field($tag)->subfield($subfield);
2907 # warn "for title, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2910 # ... and on biblio.author
2911 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.author","");
2912 if ($record->field($tag)) {
2913 if ($record->field($tag)->subfields($subfield)) {
2914 push @tags, "'".$tag.$subfield."'";
2915 push @and_or, "and";
2916 push @excluding, "";
2917 push @operator, "contains";
2918 push @value, $record->field($tag)->subfield($subfield);
2919 # warn "for author, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2922 # ... and on publicationyear.
2923 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publicationyear","");
2924 if ($record->field($tag)) {
2925 if ($record->field($tag)->subfields($subfield)) {
2926 push @tags, "'".$tag.$subfield."'";
2927 push @and_or, "and";
2928 push @excluding, "";
2929 push @operator, "=";
2930 push @value, $record->field($tag)->subfield($subfield);
2931 # warn "for publicationyear, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2935 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.size","");
2936 if ($record->field($tag)) {
2937 if ($record->field($tag)->subfields($subfield)) {
2938 push @tags, "'".$tag.$subfield."'";
2939 push @and_or, "and";
2940 push @excluding, "";
2941 push @operator, "=";
2942 push @value, $record->field($tag)->subfield($subfield);
2943 # warn "for size, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2946 # ... and on publisher.
2947 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publishercode","");
2948 if ($record->field($tag)) {
2949 if ($record->field($tag)->subfields($subfield)) {
2950 push @tags, "'".$tag.$subfield."'";
2951 push @and_or, "and";
2952 push @excluding, "";
2953 push @operator, "=";
2954 push @value, $record->field($tag)->subfield($subfield);
2955 # warn "for publishercode, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2958 # ... and on volume.
2959 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.volume","");
2960 if ($record->field($tag)) {
2961 if ($record->field($tag)->subfields($subfield)) {
2962 push @tags, "'".$tag.$subfield."'";
2963 push @and_or, "and";
2964 push @excluding, "";
2965 push @operator, "=";
2966 push @value, $record->field($tag)->subfield($subfield);
2967 # warn "for volume, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2971 my ($finalresult,$nbresult) = C4::SearchMarc::catalogsearch($dbh,\@tags,\@and_or,\@excluding,\@operator,\@value,0,10);
2972 # there is at least 1 result => return the 1st one
2974 # warn "$nbresult => ".@$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2975 return @$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2977 # no result, returns nothing
2984 if(substr($isbn, 0, 1) <=7) {
2985 $seg1 = substr($isbn, 0, 1);
2986 } elsif(substr($isbn, 0, 2) <= 94) {
2987 $seg1 = substr($isbn, 0, 2);
2988 } elsif(substr($isbn, 0, 3) <= 995) {
2989 $seg1 = substr($isbn, 0, 3);
2990 } elsif(substr($isbn, 0, 4) <= 9989) {
2991 $seg1 = substr($isbn, 0, 4);
2993 $seg1 = substr($isbn, 0, 5);
2995 my $x = substr($isbn, length($seg1));
2997 if(substr($x, 0, 2) <= 19) {
2998 # if(sTmp2 < 10) sTmp2 = "0" sTmp2;
2999 $seg2 = substr($x, 0, 2);
3000 } elsif(substr($x, 0, 3) <= 699) {
3001 $seg2 = substr($x, 0, 3);
3002 } elsif(substr($x, 0, 4) <= 8399) {
3003 $seg2 = substr($x, 0, 4);
3004 } elsif(substr($x, 0, 5) <= 89999) {
3005 $seg2 = substr($x, 0, 5);
3006 } elsif(substr($x, 0, 6) <= 9499999) {
3007 $seg2 = substr($x, 0, 6);
3009 $seg2 = substr($x, 0, 7);
3011 my $seg3=substr($x,length($seg2));
3012 $seg3=substr($seg3,0,length($seg3)-1) ;
3013 my $seg4 = substr($x, -1, 1);
3014 return "$seg1-$seg2-$seg3-$seg4";
3018 END { } # module clean-up code here (global destructor)
3024 Koha Developement team <info@koha.org>
3026 Paul POULAIN paul.poulain@free.fr
3032 # Revision 1.168 2006/04/03 04:00:02 rangi
3033 # Modify item now works
3035 # BUT only if there is only one item, if there is more than one item, it gets messed up.
3036 # They get combined into the form, ill work on this next
3038 # Revision 1.167 2006/04/03 02:12:49 kados
3039 # some modifs to improve plugin support
3041 # Revision 1.166 2006/04/01 22:10:50 rangi
3042 # Fixing the problem that all items were getting biblioitem=1 set
3044 # Revision 1.165 2006/04/01 21:22:05 rangi
3045 # Adding a little fake subroutine that a few scripts in the opac depend on, can be removed once the opac scripts are rewritten
3047 # Revision 1.164 2006/03/29 01:56:25 rangi
3048 # Delete isnt working using the extended services method
3050 # Revision 1.163 2006/03/28 23:05:08 rangi
3051 # Delete working now
3053 # Revision 1.162 2006/03/13 23:12:44 rangi
3054 # Adding commits, so that changes stick
3056 # Revision 1.161 2006/03/10 02:40:38 kados
3057 # syncing MARChtml2xml wtih rel_2_2, removing unused MARChtml2marc
3059 # Revision 1.160 2006/03/07 22:00:18 kados
3060 # adding support for 'delete' function
3062 # Revision 1.159 2006/03/07 21:54:47 rangi
3063 # Starting work on deletes
3065 # Revision 1.158 2006/03/06 02:45:41 kados
3066 # Adding fixes to MARC editor to HEAD
3068 # Revision 1.157 2006/03/01 03:07:54 kados
3069 # rollback ... by accident I committed a rel_2_2 Biblio.pm
3071 # Revision 1.155 2006/02/27 01:08:31 kados
3072 # Removing 'our Zconn' from top...
3074 # Revision 1.154 2006/02/26 00:08:20 kados
3075 # moving all $Zconn s to z3950_extended_services (currently, nothing
3078 # Revision 1.153 2006/02/25 22:39:10 kados
3079 # Another purely documentation commit. Just changing formatting to ease
3082 # Revision 1.152 2006/02/25 21:17:20 kados
3083 # Purely documentation change: converted all =head2 entries to use function
3084 # name as title rather than usage as title
3086 # Revision 1.151 2006/02/25 21:02:20 kados
3088 # Further cleanup, convering new routines to 4-chars
3090 # Revision 1.150 2006/02/25 20:49:15 kados
3091 # Better documentation, added warning if serviceType is 'drop' since it's
3092 # not supported in Zebra.
3094 # Revision 1.149 2006/02/25 20:30:32 kados
3095 # IMPORTANT: Paul, I've removed the decode_char routine because it's no
3096 # longer necessary. If we need to convert from MARC-8 for display, we should:
3099 # 2. do it with MARC::Charset
3101 # If you still need it, let me know and I'll put it back in.
3103 # Revision 1.148 2006/02/25 19:23:01 kados
3104 # cleaning up POD docs, deleting zebra_create as it's no longer used (
3105 # replaced by z3950_extended_services).
3107 # Revision 1.147 2006/02/25 19:09:59 kados
3108 # readding some lost subs
3110 # Revision 1.145 2006/02/22 01:02:39 kados
3111 # Replacing all calls to zebra_update with calls to
3112 # z3950_extended_services. More work coming, but it's
3115 # Revision 1.144 2006/02/20 14:22:38 kados
3118 # Revision 1.143 2006/02/20 13:26:11 kados
3119 # A new subroutine to handle Z39.50 extended services. You pass it a
3120 # connection object, service type, service options, and a record, and
3121 # it performs the service and handles any exception found.
3123 # Revision 1.142 2006/02/16 20:49:56 kados
3124 # destroy a connection after we're done -- we really should just have one
3125 # connection object and not destroy it until the whole transaction is
3126 # finished -- but this will do for now
3128 # Revision 1.141 2006/02/16 19:47:22 rangi
3129 # Trying to error trap a little more.
3131 # Revision 1.140 2006/02/14 21:36:03 kados
3132 # adding a 'use ZOOM' to biblio.pm, needed for non-mod_perl install.
3133 # also adding diagnostic error if not able to connect to Zebra
3135 # Revision 1.139 2006/02/14 19:53:25 rangi
3136 # Just a little missing my
3138 # Seems to be working great Paul, and I like what you did with zebradb
3140 # Revision 1.138 2006/02/14 11:25:22 tipaul
3141 # road to 3.0 : updating a biblio in zebra seems to work. Still working on it, there are probably some bugs !
3143 # Revision 1.137 2006/02/13 16:34:26 tipaul
3144 # fixing some warnings (perl -w should be quiet)
3146 # Revision 1.136 2006/01/10 17:01:29 tipaul
3147 # adding a XMLgetbiblio in Biblio.pm (1st draft, to use with zebra)
3149 # Revision 1.135 2006/01/06 16:39:37 tipaul
3150 # synch'ing head and rel_2_2 (from 2.2.5, including npl templates)
3151 # Seems not to break too many things, but i'm probably wrong here.
3152 # at least, new features/bugfixes from 2.2.5 are here (tested on some features on my head local copy)
3154 # - removing useless directories (koha-html and koha-plucene)
3156 # Revision 1.134 2006/01/04 15:54:55 tipaul
3157 # utf8 is a : go for beta test in HEAD.
3158 # some explanations :
3159 # - 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.
3160 # - *-top.inc will show the pages in utf8
3161 # - 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.
3162 # - using marcxml field and no more the iso2709 raw marc biblioitems.marc field.
3164 # Revision 1.133 2005/12/12 14:25:51 thd
3167 # Reverse array filled with elements from repeated subfields
3168 # to avoid last to first concatenation of elements in Koha DB.-
3170 # Revision 1.132 2005-10-26 09:12:33 tipaul
3171 # big commit, still breaking things...
3173 # * synch with rel_2_2. Probably the last non manual synch, as rel_2_2 should not be modified deeply.
3174 # * code cleaning (cleaning warnings from perl -w) continued
3176 # Revision 1.131 2005/09/22 10:01:45 tipaul
3177 # see mail on koha-devel : code cleaning on Search.pm + normalizing API + use of biblionumber everywhere (instead of bn, biblio, ...)
3179 # Revision 1.130 2005/09/02 14:34:14 tipaul
3180 # continuing the work to move to zebra. Begin of work for MARC=OFF support.
3181 # IMPORTANT NOTE : the MARCkoha2marc sub API has been modified. Instead of biblionumber & biblioitemnumber, it now gets a hash.
3182 # The sub is used only in Biblio.pm, so the API change should be harmless (except for me, but i'm aware ;-) )
3184 # Revision 1.129 2005/08/12 13:50:31 tipaul
3185 # removing useless sub declarations
3187 # Revision 1.128 2005/08/11 16:12:47 tipaul
3188 # Playing with the zebra...
3190 # * go to koha cvs home directory
3191 # * in misc/zebra there is a unimarc directory. I suggest that marc21 libraries create a marc21 directory
3192 # * put your zebra.cfg files here & create your database.
3193 # * from koha cvs home directory, ln -s misc/zebra/marc21 zebra (I mean create a symbolic link to YOUR zebra directory)
3194 # * now, everytime you add/modify a biblio/item your zebra DB is updated correctly.
3197 # * this uses a system call in perl. CPU consumming, but we are waiting for indexdata Perl/zoom
3198 # * deletion still not work
3199 # * UNIMARC zebra config files are provided in misc/zebra/unimarc directory. The most important line being :
3201 # recordId: (bib1,Local-number)
3205 # elm 090 Local-number -
3206 # elm 090/? Local-number -
3207 # elm 090/?/9 Local-number !:w
3209 # (090$9 being the field mapped to biblio.biblionumber in Koha)
3211 # Revision 1.127 2005/08/11 14:37:32 tipaul
3213 # * removing useless subs
3214 # * removing some subs that are also elsewhere
3215 # * 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)
3217 # Revision 1.126 2005/08/11 09:13:28 tipaul
3218 # just removing useless subs (a lot !!!) for code cleaning
3220 # Revision 1.125 2005/08/11 09:00:07 tipaul
3221 # Ok guys, this time, it seems that item add and modif begin working as expected...
3222 # Still a lot of bugs to fix, of course
3224 # Revision 1.124 2005/08/10 10:21:15 tipaul
3225 # continuing the road to zebra :
3226 # - the biblio add begins to work.
3227 # - the biblio modif begins to work.
3229 # (still without doing anything on zebra)
3230 # (no new change in updatedatabase)
3232 # Revision 1.123 2005/08/09 14:10:28 tipaul
3233 # 1st commit to go to zebra.
3234 # don't update your cvs if you want to have a working head...
3236 # this commit contains :
3237 # * 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...
3238 # * 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.
3239 # * other files : get rid of bibid and use biblionumber instead.
3242 # * does not do anything on zebra yet.
3243 # * if you rename marc_subfield_table, you can't search anymore.
3244 # * you can view a biblio & bibliodetails, go to MARC editor, but NOT save any modif.
3245 # * 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 ;-) )
3247 # 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
3248 # 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.
3250 # tipaul cutted previous commit notes