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;
30 use vars qw($VERSION @ISA @EXPORT);
32 # set the version for version checking
33 $VERSION = do { my @v = '$Revision$' =~ /\d+/g;
34 shift(@v) . "." . join("_", map {sprintf "%03d", $_ } @v); };
39 # don't forget MARCxxx subs are exported only for testing purposes. Should not be used
40 # as the old-style API and the NEW one are the only public functions.
43 &newbiblio &newbiblioitem
44 &newsubject &newsubtitle &newitems
46 &modbiblio &checkitems &modbibitem
47 &modsubtitle &modsubject &modaddauthor &moditem
49 &delitem &deletebiblioitem &delbiblio
51 &getbiblio &bibdata &bibitems &bibitemdata
52 &barcodes &ItemInfo &itemdata &itemissues &itemcount
53 &getsubject &getaddauthor &getsubtitle
54 &getwebbiblioitems &getwebsites
55 &getbiblioitembybiblionumber
56 &getbiblioitem &getitemsbybiblioitem
58 &MARCfind_marc_from_kohafield
59 &MARCfind_frameworkcode
60 &find_biblioitemnumber
63 &NEWnewbiblio &NEWnewitem
64 &NEWmodbiblio &NEWmoditem
65 &NEWdelbiblio &NEWdelitem
66 &NEWmodbiblioframework
68 &MARCkoha2marcBiblio &MARCmarc2koha
69 &MARCkoha2marcItem &MARChtml2marc &MARChtml2xml
70 &MARCgetbiblio &MARCgetitem
71 MARCfind_MARCbibid_from_oldbiblionumber
77 &z3950_extended_services
80 &get_item_from_barcode
81 &MARCfind_MARCbibid_from_oldbiblionumber
87 C4::Biblio - Acquisitions, Catalog Management Functions
91 ( lot of changes for Koha 3.X)
93 Koha 1.2 and previous versions used a specific API to manage biblios. This API uses old-DB style parameters.
94 They are based on a hash, and store data in biblio/biblioitems/items tables (plus additionalauthors,
95 bibliosubject and bibliosubtitle where applicable).
97 In Koha 2.X, we introduced a MARC-DB.
99 In Koha 3.X, we removed this MARC-DB for search as we wanted to use Zebra as search system.
101 So in Koha 3.X, saving a record means :
103 - storing the raw marc record (iso2709) in biblioitems.marc field. It contains both biblio & items information.
104 - storing the "decoded information" in biblio/biblioitems/items as previously.
105 - using zebra to manage search & indexing on the MARC data.
107 In Koha, there is a systempreference for "MARC=ON" or "MARC=OFF" :
109 * MARC=ON : when MARC=ON, Koha uses a MARC::Record object (in sub parameters). Saving information in the DB means :
111 - transform the MARC record into a hash
112 - add the raw MARC record into the hash
113 - store them & update Zebra
115 * MARC=OFF : when MARC=OFF, Koha uses a hash object (in sub parameters). Saving information in the DB means :
117 - transform the hash into a MARC record
118 - add the raw marc record into the hash
119 - store them & update zebra
121 That's why we need 3 types of subs :
125 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).
127 =head2 NEWxxx related subs
131 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.
133 all subs requires/use $dbh as 1st parameter and a MARC::Record object as 2nd parameter. They sometimes require another parameter.
137 =head2 something_elsexxx related subs
141 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.
143 all subs require/use $dbh as 1st parameter and a hash as 2nd parameter.
149 =head2 z3950_extended_services
151 z3950_extended_services($serviceType,$serviceOptions,$record);
153 z3950_extended_services is used to handle all interactions with Zebra's extended serices package.
155 C<$serviceType> one of: itemorder,create,drop,commit,update,xmlupdate
157 C<$serviceOptions> a has of key/value pairs. For instance, if service_type is 'update', $service_options should contain:
159 action => update action, one of specialUpdate, recordInsert, recordReplace, recordDelete, elementUpdate.
163 recordidOpaque => Opaque Record ID (user supplied) or recordidNumber => Record ID number (system number).
164 syntax => the record syntax (transfer syntax)
165 databaseName = Database from connection object
167 To set serviceOptions, call set_service_options($serviceType)
169 C<$record> the record, if one is needed for the service type
171 A record should be in XML. You can convert it to XML from MARC by running it through marc2xml().
174 sub z3950_extended_services {
175 my ($serviceType,$serviceOptions,$record) = @_;
177 my $Zconn = C4::Context->Zconn;
178 # create a new package object
179 my $Zpackage = $Zconn->package();
182 $Zpackage->option(action => $serviceOptions->{'action'});
184 if ($serviceOptions->{'databaseName'}) {
185 $Zpackage->option(databaseName => $serviceOptions->{'databaseName'});
187 if ($serviceOptions->{'recordIdNumber'}) {
188 $Zpackage->option(recordIdNumber => $serviceOptions->{'recordIdNumber'});
190 if ($serviceOptions->{'recordIdOpaque'}) {
191 $Zpackage->option(recordIdOpaque => $serviceOptions->{'recordIdOpaque'});
194 # this is an ILL request (Zebra doesn't support it)
195 #if ($serviceType eq 'itemorder') {
196 # $Zpackage->option('contact-name' => $serviceOptions->{'contact-name'});
197 # $Zpackage->option('contact-phone' => $serviceOptions->{'contact-phone'});
198 # $Zpackage->option('contact-email' => $serviceOptions->{'contact-email'});
199 # $Zpackage->option('itemorder-item' => $serviceOptions->{'itemorder-item'});
203 my $xmlrecord = marc2xml($record);
204 $Zpackage->option(record => $xmlrecord);
205 if ($serviceOptions->{'syntax'}) {
206 $Zpackage->option(syntax => $serviceOptions->{'syntax'});
210 # send the request, handle any exception encountered
211 eval { $Zpackage->send($serviceType) };
212 if ($@ && $@->isa("ZOOM::Exception")) {
213 print "Oops! ", $@->message(), "\n";
216 # free up package resources
217 $Zpackage->destroy();
220 =head2 set_service_options
222 my $serviceOptions = set_service_options($serviceType);
224 C<$serviceType> itemorder,create,drop,commit,update,xmlupdate
226 Currently, we only support 'create', 'commit', and 'update'. 'drop' support will be added as soon as Zebra supports it.
230 sub set_service_options {
231 my ($serviceType,$action,$recordId) = @_;
234 if ($serviceType eq 'update') {
236 $serviceOptions->{ 'action' } = $action;
238 $serviceOptions->{ 'action' } = 'specialUpdate';
241 $serviceOptions->{'recordIdNumber'} = $recordId;
244 # FIXME: This needs to be an OID ... if we ever need 'syntax' this sub will need to change
245 # $serviceOptions->{ 'syntax' } = ''; #zebra doesn't support syntaxes other than xml
248 if ($serviceType eq 'commit') {
252 if ($serviceType eq 'create') {
255 if ($serviceType eq 'drop') {
256 die "ERROR: 'drop' not currently supported (by Zebra)";
260 return $serviceOptions;
265 my $xmlrecord = marc2xml($record);
267 Convert from MARC to XML. Note that MARC::File::XML will automatically encode from MARC-8 to UTF-8 as of version .8
269 C<$record> a MARC record
276 eval { $xmlrecord=$record->as_xml() };
277 #TODO: better error handling here
279 warn "ERROR: I suspect a badly formatted MARC record";
284 =head2 MARCgettagslib
286 @tagslib = &MARCgettagslib($dbh,1|0,$frameworkcode);
290 2nd param is 1 for liblibrarian and 0 for libopac
291 $frameworkcode contains the framework reference. If empty or does not exist, the default one is used
293 returns a hash with all values for all fields and subfields for a given MARC framework :
294 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
296 ->{mandatory} = $mandatory;
297 ->{repeatable} = $repeatable;
298 ->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
300 ->{mandatory} = $mandatory;
301 ->{repeatable} = $repeatable;
302 ->{authorised_value} = $authorised_value;
303 ->{authtypecode} = $authtypecode;
304 ->{value_builder} = $value_builder;
305 ->{kohafield} = $kohafield;
306 ->{seealso} = $seealso;
307 ->{hidden} = $hidden;
316 # old subroutine to provide backwards compatibility.
317 # opac-detail breaks without this. Can be removed once opac-detail is fixed
318 sub MARCfind_MARCbibid_from_oldbiblionumber {
319 my ($biblionumber)=@_;
320 return ($biblionumber);
325 my ( $dbh, $forlibrarian, $frameworkcode ) = @_;
326 $frameworkcode = "" unless $frameworkcode;
327 $forlibrarian = 1 unless $forlibrarian;
329 my $libfield = ( $forlibrarian eq 1 ) ? 'liblibrarian' : 'libopac';
331 # check that framework exists
334 "select count(*) from marc_tag_structure where frameworkcode=?");
335 $sth->execute($frameworkcode);
336 my ($total) = $sth->fetchrow;
337 $frameworkcode = "" unless ( $total > 0 );
340 "select tagfield,liblibrarian,libopac,mandatory,repeatable from marc_tag_structure where frameworkcode=? order by tagfield"
342 $sth->execute($frameworkcode);
343 my ( $liblibrarian, $libopac, $tag, $res, $tab, $mandatory, $repeatable );
345 while ( ( $tag, $liblibrarian, $libopac, $mandatory, $repeatable ) = $sth->fetchrow ) {
346 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
347 $res->{$tag}->{tab} = ""; # XXX
348 $res->{$tag}->{mandatory} = $mandatory;
349 $res->{$tag}->{repeatable} = $repeatable;
354 "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"
356 $sth->execute($frameworkcode);
359 my $authorised_value;
369 ( $tag, $subfield, $liblibrarian, , $libopac, $tab,
370 $mandatory, $repeatable, $authorised_value, $authtypecode,
371 $value_builder, $kohafield, $seealso, $hidden,
376 $res->{$tag}->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
377 $res->{$tag}->{$subfield}->{tab} = $tab;
378 $res->{$tag}->{$subfield}->{mandatory} = $mandatory;
379 $res->{$tag}->{$subfield}->{repeatable} = $repeatable;
380 $res->{$tag}->{$subfield}->{authorised_value} = $authorised_value;
381 $res->{$tag}->{$subfield}->{authtypecode} = $authtypecode;
382 $res->{$tag}->{$subfield}->{value_builder} = $value_builder;
383 $res->{$tag}->{$subfield}->{kohafield} = $kohafield;
384 $res->{$tag}->{$subfield}->{seealso} = $seealso;
385 $res->{$tag}->{$subfield}->{hidden} = $hidden;
386 $res->{$tag}->{$subfield}->{isurl} = $isurl;
387 $res->{$tag}->{$subfield}->{link} = $link;
392 =head2 MARCfind_marc_from_kohafield
394 ($tagfield,$tagsubfield) = &MARCfind_marc_from_kohafield($dbh,$kohafield);
398 finds MARC tag and subfield for a given kohafield
399 kohafield is "table.field" where table= biblio|biblioitems|items, and field a field of the previous table
405 sub MARCfind_marc_from_kohafield {
406 my ( $dbh, $kohafield,$frameworkcode ) = @_;
407 return 0, 0 unless $kohafield;
408 $frameworkcode='' unless $frameworkcode;
409 my $relations = C4::Context->marcfromkohafield;
410 return ($relations->{$frameworkcode}->{$kohafield}->[0],$relations->{$frameworkcode}->{$kohafield}->[1]);
415 $MARCRecord = &MARCgetbiblio($dbh,$biblionumber);
419 Returns a MARC::Record for the biblio $biblionumber.
425 # Returns MARC::Record of the biblio passed in parameter.
426 my ( $dbh, $biblionumber ) = @_;
427 my $sth = $dbh->prepare('select marc from biblioitems where biblionumber=?');
428 $sth->execute($biblionumber);
429 my ($marc) = $sth->fetchrow;
430 my $record = MARC::Record::new_from_usmarc($marc);
436 $XML = &XMLgetbiblio($dbh,$biblionumber);
440 Returns a raw XML for the biblio $biblionumber.
446 # Returns MARC::Record of the biblio passed in parameter.
447 my ( $dbh, $biblionumber ) = @_;
448 my $sth = $dbh->prepare('select marcxml,marc from biblioitems where biblionumber=?');
449 $sth->execute($biblionumber);
450 my ($XML,$marc) = $sth->fetchrow;
451 # my $record =MARC::Record::new_from_usmarc($marc);
452 # warn "MARC : \n*-************************\n".$record->as_xml."\n*-************************\n";
458 $MARCrecord = &MARCgetitem($dbh,$biblionumber);
462 Returns a MARC::Record with all items of biblio # $biblionumber
470 my ( $dbh, $biblionumber, $itemnumber ) = @_;
471 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
472 # get the complete MARC record
473 my $sth = $dbh->prepare("select marc from biblioitems where biblionumber=?");
474 $sth->execute($biblionumber);
475 my ($rawmarc) = $sth->fetchrow;
476 my $record = C4::Search::get_record($biblionumber);
477 warn "ITEMRECORD".$record->as_formatted;
478 # now, find the relevant itemnumber
479 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
480 # prepare the new item record
481 my $itemrecord = MARC::Record->new();
482 # parse all fields fields from the complete record
483 foreach ($record->field($itemnumberfield)) {
484 # when the item field is found, save it
485 warn "Itenumberfield = $itemnumberfield";
486 if ($_->subfield($itemnumbersubfield) == $itemnumber) {
487 warn "Inside if subfield=$itemnumbersubfield";
488 $itemrecord->append_fields($_);
490 warn "No match subfield=$itemnumbersubfield and
491 itemnumber=$itemnumber";
494 warn "ITEMS".$itemrecord->as_formatted;
498 =head2 find_biblioitemnumber
500 my $biblioitemnumber = find_biblioitemnumber($dbh,$biblionumber);
504 Returns the 1st biblioitemnumber related to $biblionumber. When MARC=ON we should have 1 biblionumber = 1 and only 1 biblioitemnumber
505 This sub is useless when MARC=OFF
510 sub find_biblioitemnumber {
511 my ( $dbh, $biblionumber ) = @_;
512 my $sth = $dbh->prepare("select biblioitemnumber from biblioitems where biblionumber=?");
513 $sth->execute($biblionumber);
514 my ($biblioitemnumber) = $sth->fetchrow;
515 return $biblioitemnumber;
518 =head2 MARCfind_frameworkcode
520 my $frameworkcode = MARCfind_frameworkcode($dbh,$biblionumber);
524 returns the framework of a given biblio
530 sub MARCfind_frameworkcode {
531 my ( $dbh, $biblionumber ) = @_;
532 my $sth = $dbh->prepare("select frameworkcode from biblio where biblionumber=?");
533 $sth->execute($biblionumber);
534 my ($frameworkcode) = $sth->fetchrow;
535 return $frameworkcode;
538 =head2 MARCkoha2marcBiblio
540 $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibliohash);
544 MARCkoha2marcBiblio is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB biblio/biblioitem :
545 all entries of the hash are transformed into their matching MARC field/subfield.
551 sub MARCkoha2marcBiblio {
553 # this function builds partial MARC::Record from the old koha-DB fields
554 my ( $dbh, $bibliohash ) = @_;
555 # we don't have biblio entries in the hash, so we add them first
556 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
557 $sth->execute($bibliohash->{biblionumber});
558 my $biblio = $sth->fetchrow_hashref;
559 foreach (keys %$biblio) {
560 $bibliohash->{$_}=$biblio->{$_};
562 $sth = $dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
563 my $record = MARC::Record->new();
564 foreach ( keys %$bibliohash ) {
565 &MARCkoha2marcOnefield( $sth, $record, "biblio." . $_, $bibliohash->{$_}, '') if $bibliohash->{$_};
566 &MARCkoha2marcOnefield( $sth, $record, "biblioitems." . $_, $bibliohash->{$_}, '') if $bibliohash->{$_};
569 # other fields => additional authors, subjects, subtitles
570 my $sth2 = $dbh->prepare(" SELECT author FROM additionalauthors WHERE biblionumber=?");
571 $sth2->execute($bibliohash->{biblionumber});
572 while ( my $row = $sth2->fetchrow_hashref ) {
573 &MARCkoha2marcOnefield( $sth, $record, "additionalauthors.author", $bibliohash->{'author'},'' );
575 $sth2 = $dbh->prepare(" SELECT subject FROM bibliosubject WHERE biblionumber=?");
576 $sth2->execute($bibliohash->{biblionumber});
577 while ( my $row = $sth2->fetchrow_hashref ) {
578 &MARCkoha2marcOnefield( $sth, $record, "bibliosubject.subject", $row->{'subject'},'' );
580 $sth2 = $dbh->prepare(" SELECT subtitle FROM bibliosubtitle WHERE biblionumber=?");
581 $sth2->execute($bibliohash->{biblionumber});
582 while ( my $row = $sth2->fetchrow_hashref ) {
583 &MARCkoha2marcOnefield( $sth, $record, "bibliosubtitle.subtitle", $row->{'subtitle'},'' );
589 =head2 MARCkoha2marcItem
591 $MARCRecord = &MARCkoha2marcItem($dbh,$biblionumber,itemnumber);
593 MARCkoha2marcItem is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB items :
594 all entries of the hash are transformed into their matching MARC field/subfield.
602 sub MARCkoha2marcItem {
604 # this function builds partial MARC::Record from the old koha-DB fields
605 my ( $dbh, $item ) = @_;
607 # my $dbh=&C4Connect;
608 my $sth = $dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
609 my $record = MARC::Record->new();
611 foreach( keys %$item ) {
613 &MARCkoha2marcOnefield( $sth, $record, "items." . $_,
620 =head2 MARCkoha2marcOnefield
624 This sub is for internal use only, used by koha2marcBiblio & koha2marcItem
630 sub MARCkoha2marcOnefield {
631 my ( $sth, $record, $kohafieldname, $value,$frameworkcode ) = @_;
634 $sth->execute($frameworkcode,$kohafieldname);
635 if ( ( $tagfield, $tagsubfield ) = $sth->fetchrow ) {
636 if ( $record->field($tagfield) ) {
637 my $tag = $record->field($tagfield);
639 $tag->add_subfields( $tagsubfield, $value );
640 $record->delete_field($tag);
641 $record->add_fields($tag);
645 $record->add_fields( $tagfield, " ", " ", $tagsubfield => $value );
652 $XMLrecord = MARChtml2xml($rtags,$rsubfields,$rvalues,$indicator,$ind_tag);
654 transforms the parameters (coming from HTML form) into a MARC::File::XML
655 object. parameters with r are references to arrays
659 my ($tags,$subfields,$values,$indicator,$ind_tag) = @_;
661 my $xml= MARC::File::XML::header();
666 for (my $i=0;$i<=@$tags;$i++){
667 @$values[$i] =~ s/&/&/g;
668 @$values[$i] =~ s/</</g;
669 @$values[$i] =~ s/>/>/g;
670 @$values[$i] =~ s/"/"/g;
671 @$values[$i] =~ s/'/'/g;
673 if ((@$tags[$i] ne $prevtag)){
674 $j++ unless (@$tags[$i] eq "");
675 #warn "IND:".substr(@$indicator[$j],0,1).substr(@$indicator[$j],1,1)." ".@$tags[$i];
677 $xml.="</datafield>\n";
678 if ((@$tags[$i] > 10) && (@$values[$i] ne "")){
679 my $ind1 = substr(@$indicator[$j],0,1);
680 my $ind2 = substr(@$indicator[$j],1,1);
681 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
682 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
688 if (@$values[$i] ne "") {
690 if (@$tags[$i] eq "000") {
691 $xml.="<leader>@$values[$i]</leader>\n";
693 # rest of the fixed fields
694 } elsif (@$tags[$i] < 10) {
695 $xml.="<controlfield tag=\"@$tags[$i]\">@$values[$i]</controlfield>\n";
698 my $ind1 = substr(@$indicator[$j],0,1);
699 my $ind2 = substr(@$indicator[$j],1,1);
700 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
701 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
706 } else { # @$tags[$i] eq $prevtag
707 if (@$values[$i] eq "") {
711 my $ind1 = substr(@$indicator[$j],0,1);
712 my $ind2 = substr(@$indicator[$j],1,1);
713 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
716 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
719 $prevtag = @$tags[$i];
721 $xml.= MARC::File::XML::footer();
728 $hash = &MARCmarc2koha($dbh,$MARCRecord);
732 builds a hash with old-db datas from a MARC::Record
739 my ($dbh,$record,$frameworkcode) = @_;
740 my $sth=$dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
742 my $sth2=$dbh->prepare("SHOW COLUMNS from biblio");
745 while (($field)=$sth2->fetchrow) {
746 # warn "biblio.".$field;
747 $result=&MARCmarc2kohaOneField($sth,"biblio",$field,$record,$result,$frameworkcode);
749 $sth2=$dbh->prepare("SHOW COLUMNS from biblioitems");
751 while (($field)=$sth2->fetchrow) {
752 if ($field eq 'notes') { $field = 'bnotes'; }
753 # warn "biblioitems".$field;
754 $result=&MARCmarc2kohaOneField($sth,"biblioitems",$field,$record,$result,$frameworkcode);
756 $sth2=$dbh->prepare("SHOW COLUMNS from items");
758 while (($field)=$sth2->fetchrow) {
759 # warn "items".$field;
760 $result=&MARCmarc2kohaOneField($sth,"items",$field,$record,$result,$frameworkcode);
762 # additional authors : specific
763 $result = &MARCmarc2kohaOneField($sth,"bibliosubtitle","subtitle",$record,$result,$frameworkcode);
764 $result = &MARCmarc2kohaOneField($sth,"additionalauthors","additionalauthors",$record,$result,$frameworkcode);
765 # modify copyrightdate to keep only the 1st year found
766 my $temp = $result->{'copyrightdate'};
768 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
770 $result->{'copyrightdate'} = $1;
771 } else { # if no cYYYY, get the 1st date.
772 $temp =~ m/(\d\d\d\d)/;
773 $result->{'copyrightdate'} = $1;
776 # modify publicationyear to keep only the 1st year found
777 $temp = $result->{'publicationyear'};
778 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
780 $result->{'publicationyear'} = $1;
781 } else { # if no cYYYY, get the 1st date.
782 $temp =~ m/(\d\d\d\d)/;
783 $result->{'publicationyear'} = $1;
788 sub MARCmarc2kohaOneField {
790 # FIXME ? if a field has a repeatable subfield that is used in old-db, only the 1st will be retrieved...
791 my ( $sth, $kohatable, $kohafield, $record, $result,$frameworkcode ) = @_;
792 # warn "kohatable / $kohafield / $result / ";
796 ( $tagfield, $subfield ) = MARCfind_marc_from_kohafield("",$kohatable.".".$kohafield,$frameworkcode);
797 foreach my $field ( $record->field($tagfield) ) {
798 if ($field->tag()<10) {
799 if ($result->{$kohafield}) {
800 # Reverse array filled with elements from repeated subfields
801 # from first to last to avoid last to first concatenation of
802 # elements in Koha DB. -- thd.
803 $result->{$kohafield} .= " | ".reverse($field->data());
805 $result->{$kohafield} = $field->data();
808 if ( $field->subfields ) {
809 my @subfields = $field->subfields();
810 foreach my $subfieldcount ( 0 .. $#subfields ) {
811 if ($subfields[$subfieldcount][0] eq $subfield) {
812 if ( $result->{$kohafield} ) {
813 $result->{$kohafield} .= " | " . $subfields[$subfieldcount][1];
816 $result->{$kohafield} = $subfields[$subfieldcount][1];
823 # warn "OneField for $kohatable.$kohafield and $frameworkcode=> $tagfield, $subfield";
829 ($biblionumber,$biblioitemnumber) = NEWnewbibilio($dbh,$MARCRecord,$frameworkcode);
833 creates a biblio from a MARC::Record.
840 my ( $dbh,$record,$frameworkcode ) = @_;
842 my $biblioitemnumber;
843 my $olddata = MARCmarc2koha( $dbh, $record,$frameworkcode );
844 $olddata->{frameworkcode} = $frameworkcode;
845 $biblionumber = REALnewbiblio( $dbh, $olddata );
846 $olddata->{biblionumber} = $biblionumber;
847 # add biblionumber into the MARC record (it's the ID for zebra)
848 my ( $tagfield, $tagsubfield ) =
849 MARCfind_marc_from_kohafield( $dbh, "biblio.biblionumber",$frameworkcode );
853 $newfield = MARC::Field->new(
854 $tagfield, $biblionumber,
857 $newfield = MARC::Field->new(
858 $tagfield, '', '', "$tagsubfield" => $biblionumber,
861 # drop old field (just in case it already exist and create new one...
862 my $old_field = $record->field($tagfield);
863 $record->delete_field($old_field);
864 $record->add_fields($newfield);
866 #create the marc entry, that stores the rax marc record in Koha 3.0
867 $olddata->{marc} = $record->as_usmarc();
868 $olddata->{marcxml} = $record->as_xml();
869 # and create biblioitem, that's all folks !
870 $biblioitemnumber = REALnewbiblioitem( $dbh, $olddata );
872 # search subtiles, addiauthors and subjects
873 ( $tagfield, $tagsubfield ) =
874 MARCfind_marc_from_kohafield( $dbh, "additionalauthors.author",$frameworkcode );
875 my @addiauthfields = $record->field($tagfield);
876 foreach my $addiauthfield (@addiauthfields) {
877 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
878 foreach my $subfieldcount ( 0 .. $#addiauthsubfields ) {
879 REALmodaddauthor( $dbh, $biblionumber,
880 $addiauthsubfields[$subfieldcount] );
883 ( $tagfield, $tagsubfield ) =
884 MARCfind_marc_from_kohafield( $dbh, "bibliosubtitle.subtitle",$frameworkcode );
885 my @subtitlefields = $record->field($tagfield);
886 foreach my $subtitlefield (@subtitlefields) {
887 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
888 foreach my $subfieldcount ( 0 .. $#subtitlesubfields ) {
889 REALnewsubtitle( $dbh, $biblionumber,
890 $subtitlesubfields[$subfieldcount] );
893 ( $tagfield, $tagsubfield ) =
894 MARCfind_marc_from_kohafield( $dbh, "bibliosubject.subject",$frameworkcode );
895 my @subj = $record->field($tagfield);
897 foreach my $subject (@subj) {
898 my @subjsubfield = $subject->subfield($tagsubfield);
899 foreach my $subfieldcount ( 0 .. $#subjsubfield ) {
900 push @subjects, $subjsubfield[$subfieldcount];
903 REALmodsubject( $dbh, $biblionumber, 1, @subjects );
904 return ( $biblionumber, $biblioitemnumber );
907 =head2 NEWmodbilbioframework
909 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
913 modify the framework of a biblio
919 sub NEWmodbiblioframework {
920 my ($dbh,$biblionumber,$frameworkcode) =@_;
921 my $sth = $dbh->prepare("Update biblio SET frameworkcode=? WHERE biblionumber=?");
922 $sth->execute($frameworkcode,$biblionumber);
928 NEWmodbiblio($dbh,$MARCrecord,$biblionumber,$frameworkcode);
932 modify a biblio (MARC=ON)
939 my ($dbh,$record,$biblionumber,$frameworkcode) =@_;
940 $frameworkcode="" unless $frameworkcode;
941 # &MARCmodbiblio($dbh,$bibid,$record,$frameworkcode,0);
942 my $oldbiblio = MARCmarc2koha($dbh,$record,$frameworkcode);
944 $oldbiblio->{frameworkcode} = $frameworkcode;
945 #create the marc entry, that stores the rax marc record in Koha 3.0
946 $oldbiblio->{biblionumber} = $biblionumber unless $oldbiblio->{biblionumber};
947 $oldbiblio->{marc} = $record->as_usmarc();
948 $oldbiblio->{marcxml} = $record->as_xml();
949 warn "dans NEWmodbiblio $biblionumber = ".$oldbiblio->{biblionumber}." = ".$oldbiblio->{marcxml};
950 REALmodbiblio($dbh,$oldbiblio);
951 REALmodbiblioitem($dbh,$oldbiblio);
952 # now, modify addi authors, subject, addititles.
953 my ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"additionalauthors.author",$frameworkcode);
954 my @addiauthfields = $record->field($tagfield);
955 foreach my $addiauthfield (@addiauthfields) {
956 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
957 $dbh->do("delete from additionalauthors where biblionumber=$biblionumber");
958 foreach my $subfieldcount (0..$#addiauthsubfields) {
959 REALmodaddauthor($dbh,$biblionumber,$addiauthsubfields[$subfieldcount]);
962 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubtitle.subtitle",$frameworkcode);
963 my @subtitlefields = $record->field($tagfield);
964 foreach my $subtitlefield (@subtitlefields) {
965 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
966 # delete & create subtitle again because REALmodsubtitle can't handle new subtitles
968 $dbh->do("delete from bibliosubtitle where biblionumber=$biblionumber");
969 foreach my $subfieldcount (0..$#subtitlesubfields) {
970 foreach my $subtit(split /\||#/,$subtitlesubfields[$subfieldcount]) {
971 REALnewsubtitle($dbh,$biblionumber,$subtit);
975 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubject.subject",$frameworkcode);
976 my @subj = $record->field($tagfield);
978 foreach my $subject (@subj) {
979 my @subjsubfield = $subject->subfield($tagsubfield);
980 foreach my $subfieldcount (0..$#subjsubfield) {
981 push @subjects,$subjsubfield[$subfieldcount];
984 REALmodsubject($dbh,$biblionumber,1,@subjects);
988 =head2 NEWmodbilbioframework
990 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
1001 my ( $dbh, $bibid ) = @_;
1002 # my $biblio = &MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
1003 &REALdelbiblio( $dbh, $bibid );
1006 "select biblioitemnumber from biblioitems where biblionumber=?");
1007 $sth->execute($bibid);
1008 while ( my ($biblioitemnumber) = $sth->fetchrow ) {
1009 REALdelbiblioitem( $dbh, $biblioitemnumber );
1011 # &MARCdelbiblio( $dbh, $bibid, 0 );
1013 warn "heres the bibid $bibid";
1014 # my $record = C4::Search::get_record($bibid);
1015 my $record = C4::Search::get_xml_record($bibid);
1016 # z3950_extended_services('update',set_service_options('update'),$record);
1017 warn "heres the record to delete $bibid";
1018 my $Zconn = C4::Context->Zconn;
1019 my $p = $Zconn->package();
1020 $p->option(action => "recordDelete");
1021 $p->option(record => $record);
1024 # z3950_extended_services('update',set_service_options('update','recordDelete',$record));
1025 z3950_extended_services('commit');
1030 $itemnumber = NEWnewitem($dbh, $record, $biblionumber, $biblioitemnumber);
1034 creates an item from a MARC::Record
1041 my ( $dbh,$record,$biblionumber,$biblioitemnumber ) = @_;
1042 warn "here is the $biblioitemnumber";
1043 # add item in old-DB
1044 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
1045 my $item = &MARCmarc2koha( $dbh,$record,$frameworkcode );
1046 # needs old biblionumber and biblioitemnumber
1047 $item->{'biblionumber'} = $biblionumber;
1048 $item->{'biblioitemnumber'}=$biblioitemnumber;
1049 $item->{marc} = $record->as_usmarc();
1050 #warn $item->{marc};
1051 my ( $itemnumber, $error ) = &REALnewitems( $dbh, $item, $item->{barcode} );
1058 $itemnumber = NEWmoditem($dbh, $record, $biblionumber, $biblioitemnumber,$itemnumber);
1069 my ( $dbh, $record, $biblionumber, $biblioitemnumber, $itemnumber) = @_;
1071 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
1072 my $olditem = MARCmarc2koha( $dbh, $record,$frameworkcode );
1074 $olditem->{marc} = $record->as_usmarc();
1075 $olditem->{biblionumber} = $biblionumber;
1076 $olditem->{biblioitemnumber} = $biblioitemnumber;
1078 REALmoditem( $dbh, $olditem );
1084 $itemnumber = NEWdelitem($dbh, $biblionumber, $biblioitemnumber, $itemnumber);
1095 my ( $dbh, $bibid, $itemnumber ) = @_;
1096 &REALdelitem( $dbh, $itemnumber );
1097 # &MARCdelitem( $dbh, $bibid, $itemnumber );
1098 # we must now delete the item data from zebra
1102 =head2 REALnewbiblio
1104 $biblionumber = REALnewbiblio($dbh,$biblio);
1108 adds a record in biblio table. Datas are in the hash $biblio.
1115 my ( $dbh, $biblio ) = @_;
1117 $dbh->do('lock tables biblio WRITE');
1118 my $sth = $dbh->prepare("Select max(biblionumber) from biblio");
1120 my $data = $sth->fetchrow_arrayref;
1121 my $bibnum = $$data[0] + 1;
1124 if ( $biblio->{'seriestitle'} ) { $series = 1 }
1127 $dbh->prepare("insert into biblio set biblionumber=?, title=?, author=?, copyrightdate=?,
1128 serial=?, seriestitle=?, notes=?, abstract=?,
1132 $bibnum, $biblio->{'title'},
1133 $biblio->{'author'}, $biblio->{'copyrightdate'},
1134 $biblio->{'serial'}, $biblio->{'seriestitle'},
1135 $biblio->{'notes'}, $biblio->{'abstract'},
1136 $biblio->{'unititle'}
1140 $dbh->do('unlock tables');
1144 =head2 REALmodbiblio
1146 $biblionumber = REALmodbiblio($dbh,$biblio);
1150 modify a record in biblio table. Datas are in the hash $biblio.
1157 my ( $dbh, $biblio ) = @_;
1158 my $sth = $dbh->prepare("Update biblio set title=?, author=?, abstract=?, copyrightdate=?,
1159 seriestitle=?, serial=?, unititle=?, notes=?, frameworkcode=?
1160 where biblionumber = ?"
1163 $biblio->{'title'}, $biblio->{'author'},
1164 $biblio->{'abstract'}, $biblio->{'copyrightdate'},
1165 $biblio->{'seriestitle'}, $biblio->{'serial'},
1166 $biblio->{'unititle'}, $biblio->{'notes'},
1167 $biblio->{frameworkcode},
1168 $biblio->{'biblionumber'}
1171 return ( $biblio->{'biblionumber'} );
1174 =head2 REALmodsubtitle
1176 REALmodsubtitle($dbh,$bibnum,$subtitle);
1180 modify subtitles in bibliosubtitle table.
1186 sub REALmodsubtitle {
1187 my ( $dbh, $bibnum, $subtitle ) = @_;
1190 "update bibliosubtitle set subtitle = ? where biblionumber = ?");
1191 $sth->execute( $subtitle, $bibnum );
1195 =head2 REALmodaddauthor
1197 REALmodaddauthor($dbh,$bibnum,$author);
1201 adds or modify additional authors
1202 NOTE : Strange sub : seems to delete MANY and add only ONE author... maybe buggy ?
1208 sub REALmodaddauthor {
1209 my ( $dbh, $bibnum, @authors ) = @_;
1211 # my $dbh = C4Connect;
1213 $dbh->prepare("Delete from additionalauthors where biblionumber = ?");
1215 $sth->execute($bibnum);
1217 foreach my $author (@authors) {
1218 if ( $author ne '' ) {
1221 "Insert into additionalauthors set author = ?, biblionumber = ?"
1224 $sth->execute( $author, $bibnum );
1229 } # sub modaddauthor
1231 =head2 REALmodsubject
1233 $errors = REALmodsubject($dbh,$bibnum, $force, @subject);
1237 modify/adds subjects
1242 sub REALmodsubject {
1243 my ( $dbh, $bibnum, $force, @subject ) = @_;
1245 # my $dbh = C4Connect;
1246 my $count = @subject;
1248 for ( my $i = 0 ; $i < $count ; $i++ ) {
1249 $subject[$i] =~ s/^ //g;
1250 $subject[$i] =~ s/ $//g;
1253 "select * from catalogueentry where entrytype = 's' and catalogueentry = ?"
1255 $sth->execute( $subject[$i] );
1257 if ( my $data = $sth->fetchrow_hashref ) {
1260 if ( $force eq $subject[$i] || $force == 1 ) {
1262 # subject not in aut, chosen to force anway
1263 # so insert into cataloguentry so its in auth file
1266 "Insert into catalogueentry (entrytype,catalogueentry) values ('s',?)"
1269 $sth2->execute( $subject[$i] ) if ( $subject[$i] );
1274 "$subject[$i]\n does not exist in the subject authority file";
1277 "Select * from catalogueentry where entrytype = 's' and (catalogueentry like ? or catalogueentry like ? or catalogueentry like ?)"
1279 $sth2->execute( "$subject[$i] %", "% $subject[$i] %",
1281 while ( my $data = $sth2->fetchrow_hashref ) {
1282 $error .= "<br>$data->{'catalogueentry'}";
1291 $dbh->prepare("Delete from bibliosubject where biblionumber = ?");
1292 $sth->execute($bibnum);
1296 "Insert into bibliosubject (subject,biblionumber) values (?,?)");
1298 foreach $query (@subject) {
1299 $sth->execute( $query, $bibnum ) if ( $query && $bibnum );
1308 =head2 REALmodbiblioitem
1310 REALmodbiblioitem($dbh, $biblioitem);
1319 sub REALmodbiblioitem {
1320 my ( $dbh, $biblioitem ) = @_;
1323 my $sth = $dbh->prepare("update biblioitems set number=?,volume=?, volumedate=?, lccn=?,
1324 itemtype=?, url=?, isbn=?, issn=?,
1325 publishercode=?, publicationyear=?, classification=?, dewey=?,
1326 subclass=?, illus=?, pages=?, volumeddesc=?,
1327 notes=?, size=?, place=?, marc=?,
1329 where biblioitemnumber=?");
1330 $sth->execute( $biblioitem->{number}, $biblioitem->{volume}, $biblioitem->{volumedate}, $biblioitem->{lccn},
1331 $biblioitem->{itemtype}, $biblioitem->{url}, $biblioitem->{isbn}, $biblioitem->{issn},
1332 $biblioitem->{publishercode}, $biblioitem->{publicationyear}, $biblioitem->{classification}, $biblioitem->{dewey},
1333 $biblioitem->{subclass}, $biblioitem->{illus}, $biblioitem->{pages}, $biblioitem->{volumeddesc},
1334 $biblioitem->{bnotes}, $biblioitem->{size}, $biblioitem->{place}, $biblioitem->{marc},
1335 $biblioitem->{marcxml}, $biblioitem->{biblioitemnumber});
1337 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1339 z3950_extended_services('update',set_service_options('update'),$record);
1340 z3950_extended_services('commit');
1343 # warn "MOD : $biblioitem->{biblioitemnumber} = ".$biblioitem->{marc};
1346 =head2 REALnewbiblioitem
1348 REALnewbiblioitem($dbh,$biblioitem);
1352 adds a biblioitem ($biblioitem is a hash with the values)
1358 sub REALnewbiblioitem {
1359 my ( $dbh, $biblioitem ) = @_;
1361 $dbh->do("lock tables biblioitems WRITE, biblio WRITE, marc_subfield_structure READ");
1362 my $sth = $dbh->prepare("Select max(biblioitemnumber) from biblioitems");
1364 my $biblioitemnumber;
1367 $data = $sth->fetchrow_arrayref;
1368 $biblioitemnumber = $$data[0] + 1;
1370 # Insert biblioitemnumber in MARC record, we need it to manage items later...
1371 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblioitem->{biblionumber});
1372 my ($biblioitemnumberfield,$biblioitemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'biblioitems.biblioitemnumber',$frameworkcode);
1373 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1374 my $field=$record->field($biblioitemnumberfield);
1375 $field->update($biblioitemnumbersubfield => "$biblioitemnumber");
1376 $biblioitem->{marc} = $record->as_usmarc();
1377 $biblioitem->{marcxml} = $record->as_xml();
1379 $sth = $dbh->prepare( "insert into biblioitems set
1380 biblioitemnumber = ?, biblionumber = ?,
1381 volume = ?, number = ?,
1382 classification = ?, itemtype = ?,
1384 issn = ?, dewey = ?,
1385 subclass = ?, publicationyear = ?,
1386 publishercode = ?, volumedate = ?,
1387 volumeddesc = ?, illus = ?,
1388 pages = ?, notes = ?,
1390 marc = ?, place = ?,
1394 $biblioitemnumber, $biblioitem->{'biblionumber'},
1395 $biblioitem->{'volume'}, $biblioitem->{'number'},
1396 $biblioitem->{'classification'}, $biblioitem->{'itemtype'},
1397 $biblioitem->{'url'}, $biblioitem->{'isbn'},
1398 $biblioitem->{'issn'}, $biblioitem->{'dewey'},
1399 $biblioitem->{'subclass'}, $biblioitem->{'publicationyear'},
1400 $biblioitem->{'publishercode'}, $biblioitem->{'volumedate'},
1401 $biblioitem->{'volumeddesc'}, $biblioitem->{'illus'},
1402 $biblioitem->{'pages'}, $biblioitem->{'bnotes'},
1403 $biblioitem->{'size'}, $biblioitem->{'lccn'},
1404 $biblioitem->{'marc'}, $biblioitem->{'place'},
1405 $biblioitem->{marcxml},
1407 $dbh->do("unlock tables");
1408 z3950_extended_services('update',set_service_options('update'),$record);
1409 z3950_extended_services('commit');
1410 return ($biblioitemnumber);
1413 =head2 REALnewsubtitle
1415 REALnewsubtitle($dbh,$bibnum,$subtitle);
1419 create a new subtitle
1424 sub REALnewsubtitle {
1425 my ( $dbh, $bibnum, $subtitle ) = @_;
1428 "insert into bibliosubtitle set biblionumber = ?, subtitle = ?");
1429 $sth->execute( $bibnum, $subtitle ) if $subtitle;
1435 ($itemnumber,$errors)= REALnewitems($dbh,$item,$barcode);
1439 create a item. $item is a hash and $barcode the barcode.
1446 my ( $dbh, $item, $barcode ) = @_;
1448 # warn "OLDNEWITEMS";
1450 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE,marc_subfield_structure WRITE');
1451 my $sth = $dbh->prepare("Select max(itemnumber) from items");
1456 $data = $sth->fetchrow_hashref;
1457 $itemnumber = $data->{'max(itemnumber)'} + 1;
1459 # FIXME the "notforloan" field seems to be named "loan" in some places. workaround bugfix.
1460 if ( $item->{'loan'} ) {
1461 $item->{'notforloan'} = $item->{'loan'};
1463 # $item->{'biblioitemnumber'} = 1;
1464 # if dateaccessioned is provided, use it. Otherwise, set to NOW()
1465 if ( $item->{'dateaccessioned'} ) {
1466 $sth = $dbh->prepare( "Insert into items set
1467 itemnumber = ?, biblionumber = ?,
1468 multivolumepart = ?,
1469 biblioitemnumber = ?, barcode = ?,
1470 booksellerid = ?, dateaccessioned = ?,
1471 homebranch = ?, holdingbranch = ?,
1472 price = ?, replacementprice = ?,
1473 replacementpricedate = NOW(), datelastseen = NOW(),
1474 multivolume = ?, stack = ?,
1475 itemlost = ?, wthdrawn = ?,
1476 paidfor = ?, itemnotes = ?,
1477 itemcallnumber =?, notforloan = ?,
1482 $itemnumber, $item->{'biblionumber'},
1483 $item->{'multivolumepart'},
1484 $item->{'biblioitemnumber'},$item->{barcode},
1485 $item->{'booksellerid'}, $item->{'dateaccessioned'},
1486 $item->{'homebranch'}, $item->{'holdingbranch'},
1487 $item->{'price'}, $item->{'replacementprice'},
1488 $item->{multivolume}, $item->{stack},
1489 $item->{itemlost}, $item->{wthdrawn},
1490 $item->{paidfor}, $item->{'itemnotes'},
1491 $item->{'itemcallnumber'}, $item->{'notforloan'},
1494 if ( defined $sth->errstr ) {
1495 $error .= $sth->errstr;
1499 $sth = $dbh->prepare( "Insert into items set
1500 itemnumber = ?, biblionumber = ?,
1501 multivolumepart = ?,
1502 biblioitemnumber = ?, barcode = ?,
1503 booksellerid = ?, dateaccessioned = NOW(),
1504 homebranch = ?, holdingbranch = ?,
1505 price = ?, replacementprice = ?,
1506 replacementpricedate = NOW(), datelastseen = NOW(),
1507 multivolume = ?, stack = ?,
1508 itemlost = ?, wthdrawn = ?,
1509 paidfor = ?, itemnotes = ?,
1510 itemcallnumber =?, notforloan = ?,
1515 $itemnumber, $item->{'biblionumber'},
1516 $item->{'multivolumepart'},
1517 $item->{'biblioitemnumber'},$item->{barcode},
1518 $item->{'booksellerid'},
1519 $item->{'homebranch'}, $item->{'holdingbranch'},
1520 $item->{'price'}, $item->{'replacementprice'},
1521 $item->{multivolume}, $item->{stack},
1522 $item->{itemlost}, $item->{wthdrawn},
1523 $item->{paidfor}, $item->{'itemnotes'},
1524 $item->{'itemcallnumber'}, $item->{'notforloan'},
1527 if ( defined $sth->errstr ) {
1528 $error .= $sth->errstr;
1531 # item stored, now, deal with the marc part...
1532 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1533 where biblio.biblionumber=biblioitems.biblionumber and
1534 biblio.biblionumber=?");
1535 $sth->execute($item->{biblionumber});
1536 if ( defined $sth->errstr ) {
1537 $error .= $sth->errstr;
1539 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1540 warn "ERROR IN REALnewitem, MARC record not found FOR $item->{biblionumber} => $rawmarc <=" unless $rawmarc;
1541 my $record = MARC::File::USMARC::decode($rawmarc);
1542 # ok, we have the marc record, add item number to the item field (in {marc}, and add the field to the record)
1543 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1544 my $itemrecord = MARC::Record->new_from_usmarc($item->{marc});
1546 #warn $itemnumberfield;
1547 #warn $itemrecord->field($itemnumberfield);
1548 my $itemfield = $itemrecord->field($itemnumberfield);
1549 $itemfield->add_subfields($itemnumbersubfield => "$itemnumber");
1550 $record->insert_grouped_field($itemfield);
1551 # save the record into biblioitem
1552 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=?");
1553 $sth->execute($record->as_usmarc(),$record->as_xml(),$item->{biblionumber});
1554 if ( defined $sth->errstr ) {
1555 $error .= $sth->errstr;
1557 z3950_extended_services('update',set_service_options('update'),$record);
1558 z3950_extended_services('commit');
1559 $dbh->do('unlock tables');
1560 return ( $itemnumber, $error );
1563 =head2 REALmoditem($dbh,$item);
1574 my ( $dbh, $item ) = @_;
1575 $item->{'bibitemnum'} = 1;
1577 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE');
1578 $item->{'itemnum'} = $item->{'itemnumber'} unless $item->{'itemnum'};
1579 my $query = "update items set barcode=?,itemnotes=?,itemcallnumber=?,notforloan=?,location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1581 $item->{'barcode'}, $item->{'itemnotes'},
1582 $item->{'itemcallnumber'}, $item->{'notforloan'},
1583 $item->{'location'}, $item->{multivolumepart},
1584 $item->{multivolume}, $item->{stack},
1587 if ( $item->{'lost'} ne '' ) {
1588 $query = "update items set biblioitemnumber=?,barcode=?,itemnotes=?,homebranch=?,
1589 itemlost=?,wthdrawn=?,itemcallnumber=?,notforloan=?,
1590 location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1592 $item->{'bibitemnum'}, $item->{'barcode'},
1593 $item->{'itemnotes'}, $item->{'homebranch'},
1594 $item->{'lost'}, $item->{'wthdrawn'},
1595 $item->{'itemcallnumber'}, $item->{'notforloan'},
1596 $item->{'location'}, $item->{multivolumepart},
1597 $item->{multivolume}, $item->{stack},
1600 if ($item->{homebranch}) {
1601 $query.=",homebranch=?";
1602 push @bind, $item->{homebranch};
1604 if ($item->{holdingbranch}) {
1605 $query.=",holdingbranch=?";
1606 push @bind, $item->{holdingbranch};
1609 $query.=" where itemnumber=?";
1610 push @bind,$item->{'itemnum'};
1611 if ( $item->{'replacement'} ne '' ) {
1612 $query =~ s/ where/,replacementprice='$item->{'replacement'}' where/;
1614 my $sth = $dbh->prepare($query);
1615 $sth->execute(@bind);
1617 # item stored, now, deal with the marc part...
1618 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1619 where biblio.biblionumber=biblioitems.biblionumber and
1620 biblio.biblionumber=? and
1621 biblioitems.biblioitemnumber=?");
1622 $sth->execute($item->{biblionumber},$item->{biblioitemnumber});
1623 if ( defined $sth->errstr ) {
1624 $error .= $sth->errstr;
1626 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1627 warn "ERROR IN REALmoditem, MARC record not found" unless $rawmarc;
1628 # my $record = MARC::File::USMARC::decode($rawmarc);
1629 my $record=C4::Search::get_record($item->{biblionumber});
1630 # ok, we have the marc record, find the previous item record for this itemnumber and delete it
1631 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1632 # prepare the new item record
1633 my $itemrecord = MARC::File::USMARC::decode($item->{marc});
1634 my $itemfield = $itemrecord->field($itemnumberfield);
1635 $itemfield->add_subfields($itemnumbersubfield => '$itemnumber');
1636 # parse all fields fields from the complete record
1637 foreach ($record->field($itemnumberfield)) {
1638 # when the previous field is found, replace by the new one
1639 if ($_->subfield($itemnumbersubfield) == $item->{itemnum}) {
1640 $_->replace_with($itemfield);
1643 # $record->insert_grouped_field($itemfield);
1644 # save the record into biblioitem
1645 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=? and biblioitemnumber=?");
1646 $sth->execute($record->as_usmarc(),$record->as_xml(),$item->{biblionumber},$item->{biblioitemnumber});
1647 z3950_extended_services('update',set_service_options('update'),$record);
1648 z3950_extended_services('commit');
1649 if ( defined $sth->errstr ) {
1650 $error .= $sth->errstr;
1652 $dbh->do('unlock tables');
1656 =head2 REALdelitem($dbh,$itemnum);
1667 my ( $dbh, $itemnum ) = @_;
1669 # my $dbh=C4Connect;
1670 my $sth = $dbh->prepare("select * from items where itemnumber=?");
1671 $sth->execute($itemnum);
1672 my $data = $sth->fetchrow_hashref;
1674 my $query = "Insert into deleteditems set ";
1676 foreach my $temp ( keys %$data ) {
1677 $query .= "$temp = ?,";
1678 push ( @bind, $data->{$temp} );
1683 $sth = $dbh->prepare($query);
1684 $sth->execute(@bind);
1686 $sth = $dbh->prepare("Delete from items where itemnumber=?");
1687 $sth->execute($itemnum);
1693 =head2 REALdelbiblioitem($dbh,$biblioitemnumber);
1697 deletes a biblioitem
1698 NOTE : not standard sub name. Should be REALdelbiblioitem()
1704 sub REALdelbiblioitem {
1705 my ( $dbh, $biblioitemnumber ) = @_;
1707 # my $dbh = C4Connect;
1708 my $sth = $dbh->prepare( "Select * from biblioitems
1709 where biblioitemnumber = ?"
1713 $sth->execute($biblioitemnumber);
1715 if ( $results = $sth->fetchrow_hashref ) {
1719 "Insert into deletedbiblioitems (biblioitemnumber, biblionumber, volume, number, classification, itemtype,
1720 isbn, issn ,dewey ,subclass ,publicationyear ,publishercode ,volumedate ,volumeddesc ,timestamp ,illus ,
1721 pages ,notes ,size ,url ,lccn ) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
1725 $results->{biblioitemnumber}, $results->{biblionumber},
1726 $results->{volume}, $results->{number},
1727 $results->{classification}, $results->{itemtype},
1728 $results->{isbn}, $results->{issn},
1729 $results->{dewey}, $results->{subclass},
1730 $results->{publicationyear}, $results->{publishercode},
1731 $results->{volumedate}, $results->{volumeddesc},
1732 $results->{timestamp}, $results->{illus},
1733 $results->{pages}, $results->{notes},
1734 $results->{size}, $results->{url},
1738 $dbh->prepare("Delete from biblioitems where biblioitemnumber = ?");
1739 $sth2->execute($biblioitemnumber);
1744 # Now delete all the items attached to the biblioitem
1745 $sth = $dbh->prepare("Select * from items where biblioitemnumber = ?");
1746 $sth->execute($biblioitemnumber);
1748 while ( my $data = $sth->fetchrow_hashref ) {
1749 my $query = "Insert into deleteditems set ";
1751 foreach my $temp ( keys %$data ) {
1752 $query .= "$temp = ?,";
1753 push ( @bind, $data->{$temp} );
1756 my $sth2 = $dbh->prepare($query);
1757 $sth2->execute(@bind);
1760 $sth = $dbh->prepare("Delete from items where biblioitemnumber = ?");
1761 $sth->execute($biblioitemnumber);
1765 } # sub deletebiblioitem
1767 =head2 REALdelbiblio($dbh,$biblio);
1778 my ( $dbh, $biblio ) = @_;
1779 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
1780 $sth->execute($biblio);
1781 if ( my $data = $sth->fetchrow_hashref ) {
1783 my $query = "Insert into deletedbiblio set ";
1785 foreach my $temp ( keys %$data ) {
1786 $query .= "$temp = ?,";
1787 push ( @bind, $data->{$temp} );
1790 #replacing the last , by ",?)"
1792 $sth = $dbh->prepare($query);
1793 $sth->execute(@bind);
1795 $sth = $dbh->prepare("Delete from biblio where biblionumber=?");
1796 $sth->execute($biblio);
1804 $number = itemcount($biblio);
1808 returns the number of items attached to a biblio
1816 my $dbh = C4::Context->dbh;
1819 my $sth = $dbh->prepare("Select count(*) from items where biblionumber=?");
1820 $sth->execute($biblio);
1821 my $data = $sth->fetchrow_hashref;
1823 return ( $data->{'count(*)'} );
1828 $biblionumber = newbiblio($biblio);
1832 create a biblio. The parameter is a hash
1840 my $dbh = C4::Context->dbh;
1841 my $bibnum = REALnewbiblio( $dbh, $biblio );
1842 # finds new (MARC bibid
1843 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1844 # my $record = &MARCkoha2marcBiblio( $dbh, $bibnum );
1845 # MARCaddbiblio( $dbh, $record, $bibnum,'' );
1851 $biblionumber = &modbiblio($biblio);
1855 Update a biblio record.
1857 C<$biblio> is a reference-to-hash whose keys are the fields in the
1858 biblio table in the Koha database. All fields must be present, not
1859 just the ones you wish to change.
1861 C<&modbiblio> updates the record defined by
1862 C<$biblio-E<gt>{biblionumber}> with the values in C<$biblio>.
1864 C<&modbiblio> returns C<$biblio-E<gt>{biblionumber}> whether it was
1873 my $dbh = C4::Context->dbh;
1874 my $biblionumber=REALmodbiblio($dbh,$biblio);
1875 my $record = MARCkoha2marcBiblio($dbh,$biblionumber,$biblionumber);
1876 # finds new (MARC bibid
1877 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$biblionumber);
1878 MARCmodbiblio($dbh,$bibid,$record,"",0);
1879 return($biblionumber);
1882 =head2 &modsubtitle($biblionumber, $subtitle);
1886 Sets the subtitle of a book.
1888 C<$biblionumber> is the biblionumber of the book to modify.
1890 C<$subtitle> is the new subtitle.
1897 my ( $bibnum, $subtitle ) = @_;
1898 my $dbh = C4::Context->dbh;
1899 &REALmodsubtitle( $dbh, $bibnum, $subtitle );
1902 =head2 &modaddauthor($biblionumber, $author);
1906 Replaces all additional authors for the book with biblio number
1907 C<$biblionumber> with C<$author>. If C<$author> is the empty string,
1908 C<&modaddauthor> deletes all additional authors.
1915 my ( $bibnum, @authors ) = @_;
1916 my $dbh = C4::Context->dbh;
1917 &REALmodaddauthor( $dbh, $bibnum, @authors );
1918 } # sub modaddauthor
1922 $error = &modsubject($biblionumber, $force, @subjects);
1926 $force - a subject to force
1927 $error - Error message, or undef if successful.
1934 my ( $bibnum, $force, @subject ) = @_;
1935 my $dbh = C4::Context->dbh;
1936 my $error = &REALmodsubject( $dbh, $bibnum, $force, @subject );
1938 # When MARC is off, ensures that the MARC biblio table gets updated with new
1939 # subjects, of course, it deletes the biblio in marc, and then recreates.
1940 # This check is to ensure that no MARC data exists to lose.
1941 # if (C4::Context->preference("MARC") eq '0'){
1942 # warn "in modSUBJECT";
1943 # my $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibnum);
1944 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1945 # &MARCmodbiblio($dbh,$bibid, $MARCRecord);
1951 =head2 modbibitem($dbh, $biblioitem);
1955 modify a biblioitem. The parameter is a hash
1962 my ($dbh, $biblioitem) = @_;
1963 #my $dbh = C4::Context->dbh;
1964 &REALmodbiblioitem( $dbh, $biblioitem );
1967 =head2 newbiblioitem
1969 $biblioitemnumber = newbiblioitem($biblioitem)
1973 create a biblioitem, the parameter is a hash
1980 my ($dbh, $biblioitem) = @_;
1981 #my $dbh = C4::Context->dbh;
1982 # add biblio information to the hash
1983 my $MARCbiblio = MARCkoha2marcBiblio( $dbh, $biblioitem );
1984 $biblioitem->{marc} = $MARCbiblio->as_usmarc();
1985 my $bibitemnum = &REALnewbiblioitem( $dbh, $biblioitem );
1986 return ($bibitemnum);
1989 =head2 newsubtitle($biblionumber,$subtitle);
1993 insert a subtitle for $biblionumber biblio
2001 my ( $bibnum, $subtitle ) = @_;
2002 my $dbh = C4::Context->dbh;
2003 &REALnewsubtitle( $dbh, $bibnum, $subtitle );
2008 $errors = newitems($dbh, $item, @barcodes);
2012 insert items ($item is a hash)
2020 my ( $dbh, $item, @barcodes ) = @_;
2021 #my $dbh = C4::Context->dbh;
2025 foreach my $barcode (@barcodes) {
2026 # add items, one by one for each barcode.
2028 $oneitem->{barcode}= $barcode;
2029 my $MARCitem = &MARCkoha2marcItem( $dbh, $oneitem);
2030 $oneitem->{marc} = $MARCitem->as_usmarc;
2031 ( $itemnumber, $error ) = &REALnewitems( $dbh, $oneitem);
2032 # $errors .= $error;
2033 # &MARCadditem( $dbh, $MARCitem, $item->{biblionumber} );
2038 =head2 moditem($dbh,$item);
2042 modify an item ($item is a hash with all item informations)
2050 my ($dbh, $item) = @_;
2051 #my $dbh = C4::Context->dbh;
2052 &REALmoditem( $dbh, $item );
2054 &MARCkoha2marcItem( $dbh, $item->{'biblionumber'}, $item->{'itemnum'} );
2056 &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $item->{biblionumber} );
2057 &MARCmoditem( $dbh, $MARCitem, $bibid, $item->{itemnum}, 0 );
2062 $error = checkitems($count,@barcodes);
2066 check for each @barcode entry that the barcode is not a duplicate
2073 my ( $count, @barcodes ) = @_;
2074 my $dbh = C4::Context->dbh;
2076 my $sth = $dbh->prepare("Select * from items where barcode=?");
2077 for ( my $i = 0 ; $i < $count ; $i++ ) {
2078 $barcodes[$i] = uc $barcodes[$i];
2079 $sth->execute( $barcodes[$i] );
2080 if ( my $data = $sth->fetchrow_hashref ) {
2081 $error .= " Duplicate Barcode: $barcodes[$i]";
2088 =head2 delitem($itemnum);
2092 delete item $itemnum being the item number to delete
2100 my $dbh = C4::Context->dbh;
2101 &REALdelitem( $dbh, $itemnum );
2104 =head2 deletebiblioitem($biblioitemnumber);
2108 delete the biblioitem $biblioitemnumber
2114 sub deletebiblioitem {
2115 my ($biblioitemnumber) = @_;
2116 my $dbh = C4::Context->dbh;
2117 &REALdelbiblioitem( $dbh, $biblioitemnumber );
2118 } # sub deletebiblioitem
2120 =head2 delbiblio($biblionumber)
2124 delete biblio $biblionumber
2132 my $dbh = C4::Context->dbh;
2133 &REALdelbiblio( $dbh, $biblio );
2134 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $biblio );
2135 &MARCdelbiblio( $dbh, $bibid, 0 );
2140 ($count,@results) = getbiblio($biblionumber);
2144 return an array with hash of biblios.
2146 FIXME : biblionumber being the primary key, this sub will always return only 1 result, API should be modified...
2153 my ($biblionumber) = @_;
2154 my $dbh = C4::Context->dbh;
2155 my $sth = $dbh->prepare("Select * from biblio where biblionumber = ?");
2157 # || die "Cannot prepare $query\n" . $dbh->errstr;
2161 $sth->execute($biblionumber);
2163 # || die "Cannot execute $query\n" . $sth->errstr;
2164 while ( my $data = $sth->fetchrow_hashref ) {
2165 $results[$count] = $data;
2170 return ( $count, @results );
2175 $data = &bibdata($biblionumber, $type);
2177 Returns information about the book with the given biblionumber.
2179 C<$type> is ignored.
2181 C<&bibdata> returns a reference-to-hash. The keys are the fields in
2182 the C<biblio>, C<biblioitems>, and C<bibliosubtitle> tables in the
2185 In addition, C<$data-E<gt>{subject}> is the list of the book's
2186 subjects, separated by C<" , "> (space, comma, space).
2188 If there are multiple biblioitems with the given biblionumber, only
2189 the first one is considered.
2194 my ($bibnum, $type) = @_;
2195 my $dbh = C4::Context->dbh;
2196 my $sth = $dbh->prepare("Select *, biblioitems.notes AS bnotes, biblio.notes
2198 left join biblioitems on biblioitems.biblionumber = biblio.biblionumber
2199 left join bibliosubtitle on
2200 biblio.biblionumber = bibliosubtitle.biblionumber
2201 left join itemtypes on biblioitems.itemtype=itemtypes.itemtype
2202 where biblio.biblionumber = ?
2204 $sth->execute($bibnum);
2206 $data = $sth->fetchrow_hashref;
2208 # handle management of repeated subtitle
2209 $sth = $dbh->prepare("Select * from bibliosubtitle where biblionumber = ?");
2210 $sth->execute($bibnum);
2212 while (my $dat = $sth->fetchrow_hashref){
2214 $line{subtitle} = $dat->{subtitle};
2215 push @subtitles, \%line;
2217 $data->{subtitles} = \@subtitles;
2219 $sth = $dbh->prepare("Select * from bibliosubject where biblionumber = ?");
2220 $sth->execute($bibnum);
2222 while (my $dat = $sth->fetchrow_hashref){
2224 $line{subject} = $dat->{'subject'};
2225 push @subjects, \%line;
2227 $data->{subjects} = \@subjects;
2229 $sth = $dbh->prepare("Select * from additionalauthors where biblionumber = ?");
2230 $sth->execute($bibnum);
2231 while (my $dat = $sth->fetchrow_hashref){
2232 $data->{'additionalauthors'} .= "$dat->{'author'} - ";
2234 chop $data->{'additionalauthors'};
2235 chop $data->{'additionalauthors'};
2236 chop $data->{'additionalauthors'};
2241 =head2 getbiblioitem
2243 ($count,@results) = getbiblioitem($biblioitemnumber);
2247 return an array with hash of biblioitemss.
2249 FIXME : biblioitemnumber being unique, this sub will always return only 1 result, API should be modified...
2256 my ($biblioitemnum) = @_;
2257 my $dbh = C4::Context->dbh;
2258 my $sth = $dbh->prepare( "Select * from biblioitems where
2259 biblioitemnumber = ?"
2264 $sth->execute($biblioitemnum);
2266 while ( my $data = $sth->fetchrow_hashref ) {
2267 $results[$count] = $data;
2272 return ( $count, @results );
2273 } # sub getbiblioitem
2275 =head2 getbiblioitembybiblionumber
2277 ($count,@results) = getbiblioitembybiblionumber($biblionumber);
2281 return an array with hash of biblioitems for the given biblionumber.
2287 sub getbiblioitembybiblionumber {
2288 my ($biblionumber) = @_;
2289 my $dbh = C4::Context->dbh;
2290 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?");
2294 $sth->execute($biblionumber);
2296 while ( my $data = $sth->fetchrow_hashref ) {
2297 $results[$count] = $data;
2302 return ( $count, @results );
2305 =head2 getitemsbybiblioitem
2307 ($count,@results) = getitemsbybiblioitem($biblionumber);
2311 returns an array with hash of items
2317 sub getitemsbybiblioitem {
2318 my ($biblioitemnum) = @_;
2319 my $dbh = C4::Context->dbh;
2320 my $sth = $dbh->prepare( "Select * from items, biblio where
2321 biblio.biblionumber = items.biblionumber and biblioitemnumber
2325 # || die "Cannot prepare $query\n" . $dbh->errstr;
2329 $sth->execute($biblioitemnum);
2331 # || die "Cannot execute $query\n" . $sth->errstr;
2332 while ( my $data = $sth->fetchrow_hashref ) {
2333 $results[$count] = $data;
2338 return ( $count, @results );
2339 } # sub getitemsbybiblioitem
2343 @results = &ItemInfo($env, $biblionumber, $type);
2345 Returns information about books with the given biblionumber.
2347 C<$type> may be either C<intra> or anything else. If it is not set to
2348 C<intra>, then the search will exclude lost, very overdue, and
2353 C<&ItemInfo> returns a list of references-to-hash. Each element
2354 contains a number of keys. Most of them are table items from the
2355 C<biblio>, C<biblioitems>, C<items>, and C<itemtypes> tables in the
2356 Koha database. Other keys include:
2360 =item C<$data-E<gt>{branchname}>
2362 The name (not the code) of the branch to which the book belongs.
2364 =item C<$data-E<gt>{datelastseen}>
2366 This is simply C<items.datelastseen>, except that while the date is
2367 stored in YYYY-MM-DD format in the database, here it is converted to
2368 DD/MM/YYYY format. A NULL date is returned as C<//>.
2370 =item C<$data-E<gt>{datedue}>
2372 =item C<$data-E<gt>{class}>
2374 This is the concatenation of C<biblioitems.classification>, the book's
2375 Dewey code, and C<biblioitems.subclass>.
2377 =item C<$data-E<gt>{ocount}>
2379 I think this is the number of copies of the book available.
2381 =item C<$data-E<gt>{order}>
2383 If this is set, it is set to C<One Order>.
2390 my ($env,$biblionumber,$type) = @_;
2391 my $dbh = C4::Context->dbh;
2392 my $query = "SELECT *,items.notforloan as itemnotforloan FROM items, biblio, biblioitems
2393 left join itemtypes on biblioitems.itemtype = itemtypes.itemtype
2394 WHERE items.biblionumber = ?
2395 AND biblioitems.biblioitemnumber = items.biblioitemnumber
2396 AND biblio.biblionumber = items.biblionumber";
2397 $query .= " order by items.dateaccessioned desc";
2398 my $sth=$dbh->prepare($query);
2399 $sth->execute($biblionumber);
2402 while (my $data=$sth->fetchrow_hashref){
2404 my $isth=$dbh->prepare("Select issues.*,borrowers.cardnumber from issues,borrowers where itemnumber = ? and returndate is null and issues.borrowernumber=borrowers.borrowernumber");
2405 $isth->execute($data->{'itemnumber'});
2406 if (my $idata=$isth->fetchrow_hashref){
2407 $data->{borrowernumber} = $idata->{borrowernumber};
2408 $data->{cardnumber} = $idata->{cardnumber};
2409 $datedue = format_date($idata->{'date_due'});
2411 if ($datedue eq ''){
2412 my ($restype,$reserves)=C4::Reserves2::CheckReserves($data->{'itemnumber'});
2418 #get branch information.....
2419 my $bsth=$dbh->prepare("SELECT * FROM branches WHERE branchcode = ?");
2420 $bsth->execute($data->{'holdingbranch'});
2421 if (my $bdata=$bsth->fetchrow_hashref){
2422 $data->{'branchname'} = $bdata->{'branchname'};
2424 my $date=format_date($data->{'datelastseen'});
2425 $data->{'datelastseen'}=$date;
2426 $data->{'datedue'}=$datedue;
2427 # get notforloan complete status if applicable
2428 my $sthnflstatus = $dbh->prepare('select authorised_value from marc_subfield_structure where kohafield="items.notforloan"');
2429 $sthnflstatus->execute;
2430 my ($authorised_valuecode) = $sthnflstatus->fetchrow;
2431 if ($authorised_valuecode) {
2432 $sthnflstatus = $dbh->prepare("select lib from authorised_values where category=? and authorised_value=?");
2433 $sthnflstatus->execute($authorised_valuecode,$data->{itemnotforloan});
2434 my ($lib) = $sthnflstatus->fetchrow;
2435 $data->{notforloan} = $lib;
2446 ($count, @results) = &bibitems($biblionumber);
2448 Given the biblionumber for a book, C<&bibitems> looks up that book's
2449 biblioitems (different publications of the same book, the audio book
2450 and film versions, etc.).
2452 C<$count> is the number of elements in C<@results>.
2454 C<@results> is an array of references-to-hash; the keys are the fields
2455 of the C<biblioitems> and C<itemtypes> tables of the Koha database. In
2456 addition, C<itemlost> indicates the availability of the item: if it is
2457 "2", then all copies of the item are long overdue; if it is "1", then
2458 all copies are lost; otherwise, there is at least one copy available.
2464 my $dbh = C4::Context->dbh;
2465 my $sth = $dbh->prepare("SELECT biblioitems.*,
2467 MIN(items.itemlost) as itemlost,
2468 MIN(items.dateaccessioned) as dateaccessioned
2469 FROM biblioitems, itemtypes, items
2470 WHERE biblioitems.biblionumber = ?
2471 AND biblioitems.itemtype = itemtypes.itemtype
2472 AND biblioitems.biblioitemnumber = items.biblioitemnumber
2473 GROUP BY items.biblioitemnumber");
2476 $sth->execute($bibnum);
2477 while (my $data = $sth->fetchrow_hashref) {
2478 $results[$count] = $data;
2482 return($count, @results);
2488 $itemdata = &bibitemdata($biblioitemnumber);
2490 Looks up the biblioitem with the given biblioitemnumber. Returns a
2491 reference-to-hash. The keys are the fields from the C<biblio>,
2492 C<biblioitems>, and C<itemtypes> tables in the Koha database, except
2493 that C<biblioitems.notes> is given as C<$itemdata-E<gt>{bnotes}>.
2499 my $dbh = C4::Context->dbh;
2500 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");
2503 $sth->execute($bibitem);
2505 $data = $sth->fetchrow_hashref;
2512 =head2 getbibliofromitemnumber
2514 $item = &getbibliofromitemnumber($env, $dbh, $itemnumber);
2516 Looks up the item with the given itemnumber.
2518 C<$env> and C<$dbh> are ignored.
2520 C<&itemnodata> returns a reference-to-hash whose keys are the fields
2521 from the C<biblio>, C<biblioitems>, and C<items> tables in the Koha
2526 sub getbibliofromitemnumber {
2527 my ($env,$dbh,$itemnumber) = @_;
2528 $dbh = C4::Context->dbh;
2529 my $sth=$dbh->prepare("Select * from biblio,items,biblioitems
2530 where items.itemnumber = ?
2531 and biblio.biblionumber = items.biblionumber
2532 and biblioitems.biblioitemnumber = items.biblioitemnumber");
2534 $sth->execute($itemnumber);
2535 my $data=$sth->fetchrow_hashref;
2542 @barcodes = &barcodes($biblioitemnumber);
2544 Given a biblioitemnumber, looks up the corresponding items.
2546 Returns an array of references-to-hash; the keys are C<barcode> and
2549 The returned items include very overdue items, but not lost ones.
2554 #called from request.pl
2555 my ($biblioitemnumber)=@_;
2556 my $dbh = C4::Context->dbh;
2557 my $sth=$dbh->prepare("SELECT barcode, itemlost, holdingbranch FROM items
2558 WHERE biblioitemnumber = ?
2559 AND (wthdrawn <> 1 OR wthdrawn IS NULL)");
2560 $sth->execute($biblioitemnumber);
2563 while (my $data=$sth->fetchrow_hashref){
2564 $barcodes[$i]=$data;
2574 $item = &itemdata($barcode);
2576 Looks up the item with the given barcode, and returns a
2577 reference-to-hash containing information about that item. The keys of
2578 the hash are the fields from the C<items> and C<biblioitems> tables in
2583 sub get_item_from_barcode {
2585 my $dbh = C4::Context->dbh;
2586 my $sth=$dbh->prepare("Select * from items,biblioitems where barcode=?
2587 and items.biblioitemnumber=biblioitems.biblioitemnumber");
2588 $sth->execute($barcode);
2589 my $data=$sth->fetchrow_hashref;
2597 @issues = &itemissues($biblioitemnumber, $biblio);
2599 Looks up information about who has borrowed the bookZ<>(s) with the
2600 given biblioitemnumber.
2602 C<$biblio> is ignored.
2604 C<&itemissues> returns an array of references-to-hash. The keys
2605 include the fields from the C<items> table in the Koha database.
2606 Additional keys include:
2612 If the item is currently on loan, this gives the due date.
2614 If the item is not on loan, then this is either "Available" or
2615 "Cancelled", if the item has been withdrawn.
2619 If the item is currently on loan, this gives the card number of the
2620 patron who currently has the item.
2622 =item C<timestamp0>, C<timestamp1>, C<timestamp2>
2624 These give the timestamp for the last three times the item was
2627 =item C<card0>, C<card1>, C<card2>
2629 The card number of the last three patrons who borrowed this item.
2631 =item C<borrower0>, C<borrower1>, C<borrower2>
2633 The borrower number of the last three patrons who borrowed this item.
2640 my ($bibitem, $biblio)=@_;
2641 my $dbh = C4::Context->dbh;
2642 # FIXME - If this function die()s, the script will abort, and the
2643 # user won't get anything; depending on how far the script has
2644 # gotten, the user might get a blank page. It would be much better
2645 # to at least print an error message. The easiest way to do this
2646 # is to set $SIG{__DIE__}.
2647 my $sth = $dbh->prepare("Select * from items where
2648 items.biblioitemnumber = ?")
2649 || die $dbh->errstr;
2653 $sth->execute($bibitem)
2654 || die $sth->errstr;
2656 while (my $data = $sth->fetchrow_hashref) {
2657 # Find out who currently has this item.
2658 # FIXME - Wouldn't it be better to do this as a left join of
2659 # some sort? Currently, this code assumes that if
2660 # fetchrow_hashref() fails, then the book is on the shelf.
2661 # fetchrow_hashref() can fail for any number of reasons (e.g.,
2662 # database server crash), not just because no items match the
2664 my $sth2 = $dbh->prepare("select * from issues,borrowers
2665 where itemnumber = ?
2666 and returndate is NULL
2667 and issues.borrowernumber = borrowers.borrowernumber");
2669 $sth2->execute($data->{'itemnumber'});
2670 if (my $data2 = $sth2->fetchrow_hashref) {
2671 $data->{'date_due'} = $data2->{'date_due'};
2672 $data->{'card'} = $data2->{'cardnumber'};
2673 $data->{'borrower'} = $data2->{'borrowernumber'};
2675 if ($data->{'wthdrawn'} eq '1') {
2676 $data->{'date_due'} = 'Cancelled';
2678 $data->{'date_due'} = 'Available';
2684 # Find the last 3 people who borrowed this item.
2685 $sth2 = $dbh->prepare("select * from issues, borrowers
2686 where itemnumber = ?
2687 and issues.borrowernumber = borrowers.borrowernumber
2688 and returndate is not NULL
2689 order by returndate desc,timestamp desc") || die $dbh->errstr;
2690 $sth2->execute($data->{'itemnumber'}) || die $sth2->errstr;
2691 for (my $i2 = 0; $i2 < 2; $i2++) { # FIXME : error if there is less than 3 pple borrowing this item
2692 if (my $data2 = $sth2->fetchrow_hashref) {
2693 $data->{"timestamp$i2"} = $data2->{'timestamp'};
2694 $data->{"card$i2"} = $data2->{'cardnumber'};
2695 $data->{"borrower$i2"} = $data2->{'borrowernumber'};
2700 $results[$i] = $data;
2710 ($count, $subjects) = &getsubject($biblionumber);
2712 Looks up the subjects of the book with the given biblionumber. Returns
2713 a two-element list. C<$subjects> is a reference-to-array, where each
2714 element is a subject of the book, and C<$count> is the number of
2715 elements in C<$subjects>.
2721 my $dbh = C4::Context->dbh;
2722 my $sth=$dbh->prepare("Select * from bibliosubject where biblionumber=?");
2723 $sth->execute($bibnum);
2726 while (my $data=$sth->fetchrow_hashref){
2731 return($i,\@results);
2736 ($count, $authors) = &getaddauthor($biblionumber);
2738 Looks up the additional authors for the book with the given
2741 Returns a two-element list. C<$authors> is a reference-to-array, where
2742 each element is an additional author, and C<$count> is the number of
2743 elements in C<$authors>.
2749 my $dbh = C4::Context->dbh;
2750 my $sth=$dbh->prepare("Select * from additionalauthors where biblionumber=?");
2751 $sth->execute($bibnum);
2754 while (my $data=$sth->fetchrow_hashref){
2759 return($i,\@results);
2765 ($count, $subtitles) = &getsubtitle($biblionumber);
2767 Looks up the subtitles for the book with the given biblionumber.
2769 Returns a two-element list. C<$subtitles> is a reference-to-array,
2770 where each element is a subtitle, and C<$count> is the number of
2771 elements in C<$subtitles>.
2777 my $dbh = C4::Context->dbh;
2778 my $sth=$dbh->prepare("Select * from bibliosubtitle where biblionumber=?");
2779 $sth->execute($bibnum);
2782 while (my $data=$sth->fetchrow_hashref){
2787 return($i,\@results);
2793 ($count, @websites) = &getwebsites($biblionumber);
2795 Looks up the web sites pertaining to the book with the given
2798 C<$count> is the number of elements in C<@websites>.
2800 C<@websites> is an array of references-to-hash; the keys are the
2801 fields from the C<websites> table in the Koha database.
2804 #FIXME : could maybe be deleted. Otherwise, would be better in a Websites.pm package
2805 #(with add / modify / delete subs)
2808 my ($biblionumber) = @_;
2809 my $dbh = C4::Context->dbh;
2810 my $sth = $dbh->prepare("Select * from websites where biblionumber = ?");
2814 $sth->execute($biblionumber);
2815 while (my $data = $sth->fetchrow_hashref) {
2816 # FIXME - The URL scheme shouldn't be stripped off, at least
2817 # not here, since it's part of the URL, and will be useful in
2818 # constructing a link to the site. If you don't want the user
2819 # to see the "http://" part, strip that off when building the
2821 $data->{'url'} =~ s/^http:\/\///; # FIXME - Leaning toothpick
2823 $results[$count] = $data;
2828 return($count, @results);
2831 =head2 getwebbiblioitems
2833 ($count, @results) = &getwebbiblioitems($biblionumber);
2835 Given a book's biblionumber, looks up the web versions of the book
2836 (biblioitems with itemtype C<WEB>).
2838 C<$count> is the number of items in C<@results>. C<@results> is an
2839 array of references-to-hash; the keys are the items from the
2840 C<biblioitems> table of the Koha database.
2844 sub getwebbiblioitems {
2845 my ($biblionumber) = @_;
2846 my $dbh = C4::Context->dbh;
2847 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?
2848 and itemtype = 'WEB'");
2852 $sth->execute($biblionumber);
2853 while (my $data = $sth->fetchrow_hashref) {
2854 $data->{'url'} =~ s/^http:\/\///;
2855 $results[$count] = $data;
2860 return($count, @results);
2861 } # sub getwebbiblioitems
2864 my $NSB = '\x88'; # NSB : begin Non Sorting Block
2865 my $NSE = '\x89'; # NSE : Non Sorting Block end
2866 # handles non sorting blocks
2870 s/[ ]{0,1}$NSE/) /gm;
2877 my $dbh = C4::Context->dbh;
2878 my $result = MARCmarc2koha($dbh,$record,'');
2880 my ($biblionumber,$bibid,$title);
2881 # search duplicate on ISBN, easy and fast...
2882 if ($result->{isbn}) {
2883 $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=?");
2884 $sth->execute($result->{'isbn'});
2885 ($biblionumber,$bibid,$title) = $sth->fetchrow;
2886 return $biblionumber,$bibid,$title if ($biblionumber);
2888 # a more complex search : build a request for SearchMarc::catalogsearch()
2889 my (@tags, @and_or, @excluding, @operator, @value, $offset,$length);
2890 # search on biblio.title
2891 my ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.title","");
2892 if ($record->field($tag)) {
2893 if ($record->field($tag)->subfields($subfield)) {
2894 push @tags, "'".$tag.$subfield."'";
2895 push @and_or, "and";
2896 push @excluding, "";
2897 push @operator, "contains";
2898 push @value, $record->field($tag)->subfield($subfield);
2899 # warn "for title, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2902 # ... and on biblio.author
2903 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.author","");
2904 if ($record->field($tag)) {
2905 if ($record->field($tag)->subfields($subfield)) {
2906 push @tags, "'".$tag.$subfield."'";
2907 push @and_or, "and";
2908 push @excluding, "";
2909 push @operator, "contains";
2910 push @value, $record->field($tag)->subfield($subfield);
2911 # warn "for author, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2914 # ... and on publicationyear.
2915 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publicationyear","");
2916 if ($record->field($tag)) {
2917 if ($record->field($tag)->subfields($subfield)) {
2918 push @tags, "'".$tag.$subfield."'";
2919 push @and_or, "and";
2920 push @excluding, "";
2921 push @operator, "=";
2922 push @value, $record->field($tag)->subfield($subfield);
2923 # warn "for publicationyear, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2927 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.size","");
2928 if ($record->field($tag)) {
2929 if ($record->field($tag)->subfields($subfield)) {
2930 push @tags, "'".$tag.$subfield."'";
2931 push @and_or, "and";
2932 push @excluding, "";
2933 push @operator, "=";
2934 push @value, $record->field($tag)->subfield($subfield);
2935 # warn "for size, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2938 # ... and on publisher.
2939 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publishercode","");
2940 if ($record->field($tag)) {
2941 if ($record->field($tag)->subfields($subfield)) {
2942 push @tags, "'".$tag.$subfield."'";
2943 push @and_or, "and";
2944 push @excluding, "";
2945 push @operator, "=";
2946 push @value, $record->field($tag)->subfield($subfield);
2947 # warn "for publishercode, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2950 # ... and on volume.
2951 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.volume","");
2952 if ($record->field($tag)) {
2953 if ($record->field($tag)->subfields($subfield)) {
2954 push @tags, "'".$tag.$subfield."'";
2955 push @and_or, "and";
2956 push @excluding, "";
2957 push @operator, "=";
2958 push @value, $record->field($tag)->subfield($subfield);
2959 # warn "for volume, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2963 my ($finalresult,$nbresult) = C4::SearchMarc::catalogsearch($dbh,\@tags,\@and_or,\@excluding,\@operator,\@value,0,10);
2964 # there is at least 1 result => return the 1st one
2966 # warn "$nbresult => ".@$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2967 return @$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2969 # no result, returns nothing
2976 if(substr($isbn, 0, 1) <=7) {
2977 $seg1 = substr($isbn, 0, 1);
2978 } elsif(substr($isbn, 0, 2) <= 94) {
2979 $seg1 = substr($isbn, 0, 2);
2980 } elsif(substr($isbn, 0, 3) <= 995) {
2981 $seg1 = substr($isbn, 0, 3);
2982 } elsif(substr($isbn, 0, 4) <= 9989) {
2983 $seg1 = substr($isbn, 0, 4);
2985 $seg1 = substr($isbn, 0, 5);
2987 my $x = substr($isbn, length($seg1));
2989 if(substr($x, 0, 2) <= 19) {
2990 # if(sTmp2 < 10) sTmp2 = "0" sTmp2;
2991 $seg2 = substr($x, 0, 2);
2992 } elsif(substr($x, 0, 3) <= 699) {
2993 $seg2 = substr($x, 0, 3);
2994 } elsif(substr($x, 0, 4) <= 8399) {
2995 $seg2 = substr($x, 0, 4);
2996 } elsif(substr($x, 0, 5) <= 89999) {
2997 $seg2 = substr($x, 0, 5);
2998 } elsif(substr($x, 0, 6) <= 9499999) {
2999 $seg2 = substr($x, 0, 6);
3001 $seg2 = substr($x, 0, 7);
3003 my $seg3=substr($x,length($seg2));
3004 $seg3=substr($seg3,0,length($seg3)-1) ;
3005 my $seg4 = substr($x, -1, 1);
3006 return "$seg1-$seg2-$seg3-$seg4";
3010 END { } # module clean-up code here (global destructor)
3016 Koha Developement team <info@koha.org>
3018 Paul POULAIN paul.poulain@free.fr
3024 # Revision 1.167 2006/04/03 02:12:49 kados
3025 # some modifs to improve plugin support
3027 # Revision 1.166 2006/04/01 22:10:50 rangi
3028 # Fixing the problem that all items were getting biblioitem=1 set
3030 # Revision 1.165 2006/04/01 21:22:05 rangi
3031 # Adding a little fake subroutine that a few scripts in the opac depend on, can be removed once the opac scripts are rewritten
3033 # Revision 1.164 2006/03/29 01:56:25 rangi
3034 # Delete isnt working using the extended services method
3036 # Revision 1.163 2006/03/28 23:05:08 rangi
3037 # Delete working now
3039 # Revision 1.162 2006/03/13 23:12:44 rangi
3040 # Adding commits, so that changes stick
3042 # Revision 1.161 2006/03/10 02:40:38 kados
3043 # syncing MARChtml2xml wtih rel_2_2, removing unused MARChtml2marc
3045 # Revision 1.160 2006/03/07 22:00:18 kados
3046 # adding support for 'delete' function
3048 # Revision 1.159 2006/03/07 21:54:47 rangi
3049 # Starting work on deletes
3051 # Revision 1.158 2006/03/06 02:45:41 kados
3052 # Adding fixes to MARC editor to HEAD
3054 # Revision 1.157 2006/03/01 03:07:54 kados
3055 # rollback ... by accident I committed a rel_2_2 Biblio.pm
3057 # Revision 1.155 2006/02/27 01:08:31 kados
3058 # Removing 'our Zconn' from top...
3060 # Revision 1.154 2006/02/26 00:08:20 kados
3061 # moving all $Zconn s to z3950_extended_services (currently, nothing
3064 # Revision 1.153 2006/02/25 22:39:10 kados
3065 # Another purely documentation commit. Just changing formatting to ease
3068 # Revision 1.152 2006/02/25 21:17:20 kados
3069 # Purely documentation change: converted all =head2 entries to use function
3070 # name as title rather than usage as title
3072 # Revision 1.151 2006/02/25 21:02:20 kados
3074 # Further cleanup, convering new routines to 4-chars
3076 # Revision 1.150 2006/02/25 20:49:15 kados
3077 # Better documentation, added warning if serviceType is 'drop' since it's
3078 # not supported in Zebra.
3080 # Revision 1.149 2006/02/25 20:30:32 kados
3081 # IMPORTANT: Paul, I've removed the decode_char routine because it's no
3082 # longer necessary. If we need to convert from MARC-8 for display, we should:
3085 # 2. do it with MARC::Charset
3087 # If you still need it, let me know and I'll put it back in.
3089 # Revision 1.148 2006/02/25 19:23:01 kados
3090 # cleaning up POD docs, deleting zebra_create as it's no longer used (
3091 # replaced by z3950_extended_services).
3093 # Revision 1.147 2006/02/25 19:09:59 kados
3094 # readding some lost subs
3096 # Revision 1.145 2006/02/22 01:02:39 kados
3097 # Replacing all calls to zebra_update with calls to
3098 # z3950_extended_services. More work coming, but it's
3101 # Revision 1.144 2006/02/20 14:22:38 kados
3104 # Revision 1.143 2006/02/20 13:26:11 kados
3105 # A new subroutine to handle Z39.50 extended services. You pass it a
3106 # connection object, service type, service options, and a record, and
3107 # it performs the service and handles any exception found.
3109 # Revision 1.142 2006/02/16 20:49:56 kados
3110 # destroy a connection after we're done -- we really should just have one
3111 # connection object and not destroy it until the whole transaction is
3112 # finished -- but this will do for now
3114 # Revision 1.141 2006/02/16 19:47:22 rangi
3115 # Trying to error trap a little more.
3117 # Revision 1.140 2006/02/14 21:36:03 kados
3118 # adding a 'use ZOOM' to biblio.pm, needed for non-mod_perl install.
3119 # also adding diagnostic error if not able to connect to Zebra
3121 # Revision 1.139 2006/02/14 19:53:25 rangi
3122 # Just a little missing my
3124 # Seems to be working great Paul, and I like what you did with zebradb
3126 # Revision 1.138 2006/02/14 11:25:22 tipaul
3127 # road to 3.0 : updating a biblio in zebra seems to work. Still working on it, there are probably some bugs !
3129 # Revision 1.137 2006/02/13 16:34:26 tipaul
3130 # fixing some warnings (perl -w should be quiet)
3132 # Revision 1.136 2006/01/10 17:01:29 tipaul
3133 # adding a XMLgetbiblio in Biblio.pm (1st draft, to use with zebra)
3135 # Revision 1.135 2006/01/06 16:39:37 tipaul
3136 # synch'ing head and rel_2_2 (from 2.2.5, including npl templates)
3137 # Seems not to break too many things, but i'm probably wrong here.
3138 # at least, new features/bugfixes from 2.2.5 are here (tested on some features on my head local copy)
3140 # - removing useless directories (koha-html and koha-plucene)
3142 # Revision 1.134 2006/01/04 15:54:55 tipaul
3143 # utf8 is a : go for beta test in HEAD.
3144 # some explanations :
3145 # - 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.
3146 # - *-top.inc will show the pages in utf8
3147 # - 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.
3148 # - using marcxml field and no more the iso2709 raw marc biblioitems.marc field.
3150 # Revision 1.133 2005/12/12 14:25:51 thd
3153 # Reverse array filled with elements from repeated subfields
3154 # to avoid last to first concatenation of elements in Koha DB.-
3156 # Revision 1.132 2005-10-26 09:12:33 tipaul
3157 # big commit, still breaking things...
3159 # * synch with rel_2_2. Probably the last non manual synch, as rel_2_2 should not be modified deeply.
3160 # * code cleaning (cleaning warnings from perl -w) continued
3162 # Revision 1.131 2005/09/22 10:01:45 tipaul
3163 # see mail on koha-devel : code cleaning on Search.pm + normalizing API + use of biblionumber everywhere (instead of bn, biblio, ...)
3165 # Revision 1.130 2005/09/02 14:34:14 tipaul
3166 # continuing the work to move to zebra. Begin of work for MARC=OFF support.
3167 # IMPORTANT NOTE : the MARCkoha2marc sub API has been modified. Instead of biblionumber & biblioitemnumber, it now gets a hash.
3168 # The sub is used only in Biblio.pm, so the API change should be harmless (except for me, but i'm aware ;-) )
3170 # Revision 1.129 2005/08/12 13:50:31 tipaul
3171 # removing useless sub declarations
3173 # Revision 1.128 2005/08/11 16:12:47 tipaul
3174 # Playing with the zebra...
3176 # * go to koha cvs home directory
3177 # * in misc/zebra there is a unimarc directory. I suggest that marc21 libraries create a marc21 directory
3178 # * put your zebra.cfg files here & create your database.
3179 # * from koha cvs home directory, ln -s misc/zebra/marc21 zebra (I mean create a symbolic link to YOUR zebra directory)
3180 # * now, everytime you add/modify a biblio/item your zebra DB is updated correctly.
3183 # * this uses a system call in perl. CPU consumming, but we are waiting for indexdata Perl/zoom
3184 # * deletion still not work
3185 # * UNIMARC zebra config files are provided in misc/zebra/unimarc directory. The most important line being :
3187 # recordId: (bib1,Local-number)
3191 # elm 090 Local-number -
3192 # elm 090/? Local-number -
3193 # elm 090/?/9 Local-number !:w
3195 # (090$9 being the field mapped to biblio.biblionumber in Koha)
3197 # Revision 1.127 2005/08/11 14:37:32 tipaul
3199 # * removing useless subs
3200 # * removing some subs that are also elsewhere
3201 # * 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)
3203 # Revision 1.126 2005/08/11 09:13:28 tipaul
3204 # just removing useless subs (a lot !!!) for code cleaning
3206 # Revision 1.125 2005/08/11 09:00:07 tipaul
3207 # Ok guys, this time, it seems that item add and modif begin working as expected...
3208 # Still a lot of bugs to fix, of course
3210 # Revision 1.124 2005/08/10 10:21:15 tipaul
3211 # continuing the road to zebra :
3212 # - the biblio add begins to work.
3213 # - the biblio modif begins to work.
3215 # (still without doing anything on zebra)
3216 # (no new change in updatedatabase)
3218 # Revision 1.123 2005/08/09 14:10:28 tipaul
3219 # 1st commit to go to zebra.
3220 # don't update your cvs if you want to have a working head...
3222 # this commit contains :
3223 # * 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...
3224 # * 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.
3225 # * other files : get rid of bibid and use biblionumber instead.
3228 # * does not do anything on zebra yet.
3229 # * if you rename marc_subfield_table, you can't search anymore.
3230 # * you can view a biblio & bibliodetails, go to MARC editor, but NOT save any modif.
3231 # * 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 ;-) )
3233 # 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
3234 # 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.
3236 # tipaul cutted previous commit notes