2 # New subs added by tgarip@neu.edu.tr 05/11/05
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
23 use MARC::File::USMARC;
28 use vars qw($VERSION @ISA @EXPORT);
30 # set the version for version checking
35 # &itemcount removed, now resides in Search.pm
49 &NEWmodbiblioframework
52 &MARCfind_marc_from_kohafield
53 &MARCfind_frameworkcode
60 &MARCkoha2marcOnefield
61 &MARCfind_attr_from_kohafield
79 &ZEBRAop &ZEBRAopserver
81 &ZEBRA_readyXML_noheader
89 #################### XML XML XML XML ###################
90 ### XML Read- Write functions
94 my ($xml,$kohafield,$recordtype)=@_;
95 #$xml represents one record node hashed of holdings or a complete xml koharecord
96 ### $recordtype is needed for reading the child records( like holdings records) .Otherwise main record is assumed ( like biblio)
97 ## holding records are parsed and sent here one by one
98 my ($tag,$subf)=MARCfind_marc_from_kohafield($kohafield,$recordtype);
101 if ($recordtype eq "holdings"){
102 my $item=$xml->{'datafield'};
103 my $hcontrolfield=$xml->{'controlfield'};
105 foreach my $data (@$item){
106 if ($data->{'tag'} eq $tag){
107 foreach my $subfield ( $data->{'subfield'}){
108 foreach my $code ( @$subfield){
109 if ($code->{'code'} eq $subf){
110 return Encode::decode("UTF-8",$code->{content});
117 foreach my $control (@$hcontrolfield){
118 if ($control->{'tag'} eq $tag){
119 return Encode::decode("UTF-8",$control->{'content'});
124 }else{ ##Not a holding read biblio
125 my $biblio=$xml->{'record'}->[0]->{'datafield'};
126 my $controlfields=$xml->{'record'}->[0]->{'controlfield'};
128 foreach my $data (@$biblio){
129 if ($data->{'tag'} eq $tag){
130 foreach my $subfield ( $data->{'subfield'}){
131 foreach my $code ( @$subfield){
132 if ($code->{'code'} eq $subf){
133 return Encode::decode("UTF-8",$code->{'content'});
141 foreach my $control (@$controlfields){
142 if ($control->{'tag'} eq $tag){
143 return Encode::decode("UTF-8",$control->{'content'}) if $control->{'content'};
153 ## This routine modifies one line of marcxml record mainly useful for updating circulation data
154 my ($xml,$kohafield,$newvalue,$recordtype)=@_;
155 my $biblio=$xml->{'record'}->[0]->{'datafield'};
156 my $controlfield=$xml->{'record'}->[0]->{'controlfield'};
157 my ($tag,$subf)=MARCfind_kohafield($kohafield,$recordtype);
160 foreach my $data (@$biblio){
161 if ($data->{'tag'} eq $tag){
162 my @subfields=$data->{'subfield'};
163 foreach my $subfield ( @subfields){
164 foreach my $code ( @$subfield){
165 if ($code->{'code'} eq $subf){
166 $code->{content}=$newvalue;
172 push @subfields,{code=>$subf,content=>$newvalue};
173 $data->{subfield}= \@subfields;
180 push @$biblio,{datafield=>[{
185 'content' => $newvalue,
194 foreach my $control(@$controlfield){
195 if ($control->{'tag'} eq $tag){
196 $control->{'content'}=$newvalue;
201 push @$controlfield,{tag=>$tag,content=>$newvalue};
208 ##make a perl hash from xml file
210 my $hashed = XMLin( $xml ,KeyAttr =>['leader','controlfield','datafield'],ForceArray => ['leader','controlfield','datafield','subfield','holdings','record'],KeepRoot=>0);
215 ## turn a hash back to xml
216 my ($hashed,$root)=@_;
217 $root="record" unless $root;
218 my $xml= XMLout($hashed,KeyAttr=>['collection','record','leader','controlfıeld','datafield'],NoSort => 1,AttrIndent => 0,KeepRoot=>0,SuppressEmpty => 1,RootName=>$root);
224 # Returns MARC::XML of the biblionumber passed in parameter.
225 my ( $dbh, $biblionumber ) = @_;
226 my $sth = $dbh->prepare("select marcxml from biblio where biblionumber=? " );
227 $sth->execute( $biblionumber);
228 my ($marcxml)=$sth->fetchrow;
233 # Returns MARC::XML of the item passed in parameter uses either itemnumber or barcode
234 my ( $dbh, $itemnumber,$barcode ) = @_;
237 $sth = $dbh->prepare("select marcxml from items where itemnumber=?" );
238 $sth->execute($itemnumber);
240 $sth = $dbh->prepare("select marcxml from items where barcode=?" );
241 $sth->execute($barcode);
243 my ($marcxml)=$sth->fetchrow;
248 # warn "XMLgetallitems";
249 # Returns an array of MARC:XML of the items passed in parameter as biblionumber
250 my ( $dbh, $biblionumber ) = @_;
252 my $sth = $dbh->prepare("select marcxml from items where biblionumber =?" );
253 $sth->execute($biblionumber);
255 while(my ($marcxml)=$sth->fetchrow_array){
256 push @results,$marcxml;
262 # warn "XMLmarc2koha";
263 ##Returns two hashes from KOHA_XML record
264 ## A biblio hash and and array of item hashes
265 my ($dbh,$xml,$related_record,@fields) = @_;
268 ## if @fields is given do not bother about the rest of fields just parse those
270 if ($related_record eq "biblios" || $related_record eq "" || !$related_record){
272 foreach my $field(@fields){
273 my $val=&XML_readline($xml,$field,'biblios');
274 $result->{$field}=$val if $val;
278 my $sth2=$dbh->prepare("SELECT marctokoha from koha_attr where recordtype like 'biblios' and tagfield is not null" );
281 while ($field=$sth2->fetchrow) {
282 $result->{$field}=&XML_readline($xml,$field,'biblios');
286 ## we only need the following for biblio data
288 # modify copyrightdate to keep only the 1st year found
289 my $temp = $result->{'copyrightdate'};
290 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
292 $result->{'copyrightdate'} = $1;
293 } else { # if no cYYYY, get the 1st date.
294 $temp =~ m/(\d\d\d\d)/;
295 $result->{'copyrightdate'} = $1;
297 # modify publicationyear to keep only the 1st year found
298 $temp = $result->{'publicationyear'};
299 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
301 $result->{'publicationyear'} = $1;
302 } else { # if no cYYYY, get the 1st date.
303 $temp =~ m/(\d\d\d\d)/;
304 $result->{'publicationyear'} = $1;
307 if ($related_record eq "holdings" || $related_record eq "" || !$related_record){
308 my $holdings=$xml->{holdings}->[0]->{record};
312 foreach my $holding (@$holdings){
314 foreach my $field(@fields){
315 my $val=&XML_readline($holding,$field,'holdings');
316 $itemresult->{$field}=$val if $val;
318 push @items, $itemresult;
321 my $sth2=$dbh->prepare("SELECT marctokoha from koha_attr where recordtype like 'holdings' and tagfield is not null" );
322 foreach my $holding (@$holdings){
326 while ($field=$sth2->fetchrow) {
327 $itemresult->{$field}=&XML_readline($xml,$field,'holdings');
329 push @items, $itemresult;
335 return ($result,@items);
340 # MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC
342 ## Script to deal with MARC read write operations
345 ##Sub to match kohafield to Z3950 -attributes
347 sub MARCfind_attr_from_kohafield {
348 # warn "MARCfind_attr_from_kohafield";
350 my ( $kohafield ) = @_;
351 return 0, 0 unless $kohafield;
353 my $relations = C4::Context->attrfromkohafield;
354 return ($relations->{$kohafield});
359 # warn "MARCgettagslib";
360 my ( $dbh, $forlibrarian, $frameworkcode ) = @_;
361 $frameworkcode = "" unless $frameworkcode;
363 my $libfield = ( $forlibrarian eq 1 ) ? 'liblibrarian' : 'libopac';
365 # check that framework exists
368 "select count(*) from biblios_tag_structure where frameworkcode=?");
369 $sth->execute($frameworkcode);
370 my ($total) = $sth->fetchrow;
371 $frameworkcode = "" unless ( $total > 0 );
374 "select tagfield,liblibrarian,libopac,mandatory,repeatable from biblios_tag_structure where frameworkcode=? order by tagfield"
376 $sth->execute($frameworkcode);
377 my ( $liblibrarian, $libopac, $tag, $res, $tab, $mandatory, $repeatable );
379 while ( ( $tag, $liblibrarian, $libopac, $mandatory, $repeatable ) = $sth->fetchrow ) {
380 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
381 $res->{$tab}->{tab} = ""; # XXX
382 $res->{$tag}->{mandatory} = $mandatory;
383 $res->{$tag}->{repeatable} = $repeatable;
388 "select tagfield,tagsubfield,liblibrarian,libopac,tab, mandatory, repeatable,authorised_value,authtypecode,value_builder,seealso,hidden,isurl,link from biblios_subfield_structure where frameworkcode=? order by tagfield,tagsubfield"
390 $sth->execute($frameworkcode);
393 my $authorised_value;
403 ( $tag, $subfield, $liblibrarian, , $libopac, $tab,
404 $mandatory, $repeatable, $authorised_value, $authtypecode,
405 $value_builder, $seealso, $hidden,
410 $res->{$tag}->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
411 $res->{$tag}->{$subfield}->{tab} = $tab;
412 $res->{$tag}->{$subfield}->{mandatory} = $mandatory;
413 $res->{$tag}->{$subfield}->{repeatable} = $repeatable;
414 $res->{$tag}->{$subfield}->{authorised_value} = $authorised_value;
415 $res->{$tag}->{$subfield}->{authtypecode} = $authtypecode;
416 $res->{$tag}->{$subfield}->{value_builder} = $value_builder;
417 $res->{$tag}->{$subfield}->{seealso} = $seealso;
418 $res->{$tag}->{$subfield}->{hidden} = $hidden;
419 $res->{$tag}->{$subfield}->{isurl} = $isurl;
420 $res->{$tag}->{$subfield}->{link} = $link;
424 sub MARCitemsgettagslib {
425 # warn "MARCitemsgettagslib";
426 my ( $dbh, $forlibrarian, $frameworkcode ) = @_;
427 $frameworkcode = "" unless $frameworkcode;
429 my $libfield = ( $forlibrarian eq 1 ) ? 'liblibrarian' : 'libopac';
431 # check that framework exists
434 "select count(*) from holdings_tag_structure where frameworkcode=?");
435 $sth->execute($frameworkcode);
436 my ($total) = $sth->fetchrow;
437 $frameworkcode = "" unless ( $total > 0 );
440 "select tagfield,liblibrarian,libopac,mandatory,repeatable from holdings_tag_structure where frameworkcode=? order by tagfield"
442 $sth->execute($frameworkcode);
443 my ( $liblibrarian, $libopac, $tag, $res, $tab, $mandatory, $repeatable );
445 while ( ( $tag, $liblibrarian, $libopac, $mandatory, $repeatable ) = $sth->fetchrow ) {
446 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
447 $res->{$tab}->{tab} = ""; # XXX
448 $res->{$tag}->{mandatory} = $mandatory;
449 $res->{$tag}->{repeatable} = $repeatable;
454 "select tagfield,tagsubfield,liblibrarian,libopac,tab, mandatory, repeatable,authorised_value,authtypecode,value_builder,seealso,hidden,isurl,link from holdings_subfield_structure where frameworkcode=? order by tagfield,tagsubfield"
456 $sth->execute($frameworkcode);
459 my $authorised_value;
469 ( $tag, $subfield, $liblibrarian, , $libopac, $tab,
470 $mandatory, $repeatable, $authorised_value, $authtypecode,
471 $value_builder, $seealso, $hidden,
476 $res->{$tag}->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
477 $res->{$tag}->{$subfield}->{tab} = $tab;
478 $res->{$tag}->{$subfield}->{mandatory} = $mandatory;
479 $res->{$tag}->{$subfield}->{repeatable} = $repeatable;
480 $res->{$tag}->{$subfield}->{authorised_value} = $authorised_value;
481 $res->{$tag}->{$subfield}->{authtypecode} = $authtypecode;
482 $res->{$tag}->{$subfield}->{value_builder} = $value_builder;
483 $res->{$tag}->{$subfield}->{seealso} = $seealso;
484 $res->{$tag}->{$subfield}->{hidden} = $hidden;
485 $res->{$tag}->{$subfield}->{isurl} = $isurl;
486 $res->{$tag}->{$subfield}->{link} = $link;
490 sub MARCfind_marc_from_kohafield {
491 # warn "MARCfind_marc_from_kohafield";
492 my ( $kohafield,$recordtype) = @_;
493 return 0, 0 unless $kohafield;
494 $recordtype="biblios" unless $recordtype;
495 my $relations = C4::Context->marcfromkohafield;
496 return ($relations->{$recordtype}->{$kohafield}->[0],$relations->{$recordtype}->{$kohafield}->[1]);
502 # Returns MARC::Record of the biblio passed in parameter.
503 ### Takes a new parameter of $title_author =1 which parses the record obly on those fields and nothing else
504 ### Its useful when Koha requires only title&author for performance issues
505 my ( $dbh, $biblionumber, $title_author ) = @_;
507 $dbh->prepare("select marc from biblio where biblionumber=? " );
508 $sth->execute( $biblionumber);
509 my ($marc)=$sth->fetchrow;
512 $record = MARC::File::USMARC::decode($marc,\&func_title_author);
514 $record = MARC::File::USMARC::decode($marc);
525 # warn "MARCgetitem";
526 # Returns MARC::Record of the item passed in parameter uses either itemnumber or barcode
527 my ( $dbh, $itemnumber,$barcode ) = @_;
530 $sth = $dbh->prepare("select i.marc from items i where i.itemnumber=?" );
531 $sth->execute($itemnumber);
533 $sth = $dbh->prepare("select i.marc from items i where i.barcode=?" );
534 $sth->execute($barcode);
536 my ($marc)=$sth->fetchrow;
537 my $record = MARC::File::USMARC::decode($marc);
542 sub MARCgetallitems {
543 # warn "MARCgetallitems";
544 # Returns an array of MARC::Record of the items passed in parameter as biblionumber
545 my ( $dbh, $biblionumber ) = @_;
547 my $sth = $dbh->prepare("select marc from items where biblionumber =?" );
548 $sth->execute($biblionumber);
550 while(my ($marc)=$sth->fetchrow_array){
551 my $record = MARC::File::USMARC::decode($marc);
552 push @results,$record;
557 sub MARCmoditemonefield{
558 # This routine will be depraeciated as soon as mysql dependency on items is removed;
559 ## this function is different to MARCkoha2marcOnefield this one does not need the record but the itemnumber
560 my ($dbh,$biblionumber,$itemnumber,$itemfield,$newvalue,$donotupdate)=@_;
561 my ($record) = MARCgetitem($dbh,$itemnumber);
562 MARCkoha2marcOnefield( $record, $itemfield, $newvalue,"holdings" );
564 ## Prevent various update calls to zebra wait until all changes finish
565 ## Fix to pass this record around to prevent Mysql update as well
566 my $sth=$dbh->prepare("update items set marc=? where itemnumber=?");
567 $sth->execute($record->as_usmarc,$itemnumber);
570 NEWmoditem($dbh,$record,$biblionumber,$itemnumber);
578 sub MARCfind_frameworkcode {
579 # warn "MARCfind_frameworkcode";
580 my ( $dbh, $biblionumber ) = @_;
582 $dbh->prepare("select frameworkcode from biblio where biblionumber=?");
583 $sth->execute($biblionumber);
584 my ($frameworkcode) = $sth->fetchrow;
585 return $frameworkcode;
587 sub MARCfind_itemtype {
588 # warn "MARCfind_itemtype";
589 my ( $dbh, $biblionumber ) = @_;
591 $dbh->prepare("select itemtype from biblio where biblionumber=?");
592 $sth->execute($biblionumber);
593 my ($itemtype) = $sth->fetchrow;
600 # warn "MARChtml2xml ";
601 my ($tags,$subfields,$values,$indicator,$ind_tag) = @_;
602 # use MARC::File::XML;
603 my $xml= marc_record_header('UTF-8'); #### we do not need a collection wrapper
609 for (my $i=0;$i<=@$tags;$i++){
610 @$values[$i] =~ s/&/&/g;
611 @$values[$i] =~ s/</</g;
612 @$values[$i] =~ s/>/>/g;
613 @$values[$i] =~ s/"/"/g;
614 @$values[$i] =~ s/'/'/g;
616 if ((@$tags[$i] ne $prevtag)){
617 $j++ unless (@$tags[$i] eq "");
618 ## warn "IND:".substr(@$indicator[$j],0,1).substr(@$indicator[$j],1,1)." ".@$tags[$i];
620 $xml.="</datafield>\n";
621 if ((@$tags[$i] > 10) && (@$values[$i] ne "")){
622 my $ind1 = substr(@$indicator[$j],0,1);
623 my $ind2 = substr(@$indicator[$j],1,1);
624 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
625 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
631 if (@$values[$i] ne "") {
633 if (@$tags[$i] eq "000") {
634 $xml.="<leader>@$values[$i]</leader>\n";
636 # rest of the fixed fields
637 } elsif (@$tags[$i] < 10) {
638 $xml.="<controlfield tag=\"@$tags[$i]\">@$values[$i]</controlfield>\n";
641 my $ind1 = substr(@$indicator[$j],0,1);
642 my $ind2 = substr(@$indicator[$j],1,1);
643 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
644 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
649 } else { # @$tags[$i] eq $prevtag
650 if (@$values[$i] eq "") {
654 my $ind1 = substr(@$indicator[$j],0,1);
655 my $ind2 = substr(@$indicator[$j],1,1);
656 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
659 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
662 $prevtag = @$tags[$i];
668 sub marc_record_header {
669 #### this one is for <record>
671 my $enc = shift || 'UTF-8';
672 return( <<MARC_XML_HEADER );
673 <?xml version="1.0" encoding="$enc"?>
675 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
676 xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"
677 xmlns="http://www.loc.gov/MARC21/slim">
682 sub collection_header {
683 #### this one is for koha collection
685 my $enc = shift || 'UTF-8';
686 return( <<KOHA_XML_HEADER );
687 <?xml version="1.0" encoding="$enc"?>
688 <kohacollection xmlns:marc="http://loc.gov/MARC21/slim" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://library.neu.edu.tr/kohanamespace/koharecord.xsd">
693 # warn "MARChtml2marc";
694 my ($dbh,$rtags,$rsubfields,$rvalues,%indicators) = @_;
696 my $record = MARC::Record->new();
697 # my %subfieldlist=();
698 my $prevvalue; # if tag <10
699 my $field; # if tag >=10
700 for (my $i=0; $i< @$rtags; $i++) {
701 next unless @$rvalues[$i];
702 # rebuild MARC::Record
703 # # warn "0=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ";
704 if (@$rtags[$i] ne $prevtag) {
708 if ($prevtag ne '000') {
709 $record->insert_fields_ordered((sprintf "%03s",$prevtag),$prevvalue);
712 $record->leader($prevvalue);
718 $record->insert_fields_ordered($field);
721 $indicators{@$rtags[$i]}.=' ';
722 if (@$rtags[$i] <10) {
723 $prevvalue= @$rvalues[$i];
727 $field = MARC::Field->new( (sprintf "%03s",@$rtags[$i]), substr($indicators{@$rtags[$i]},0,1),substr($indicators{@$rtags[$i]},1,1), @$rsubfields[$i] => @$rvalues[$i]);
728 # # warn "1=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ".$field->as_formatted;
730 $prevtag = @$rtags[$i];
732 if (@$rtags[$i] <10) {
733 $prevvalue=@$rvalues[$i];
735 if (length(@$rvalues[$i])>0) {
736 $field->add_subfields(@$rsubfields[$i] => @$rvalues[$i]);
737 # # warn "2=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ".$field->as_formatted;
740 $prevtag= @$rtags[$i];
743 # the last has not been included inside the loop... do it now !
744 $record->insert_fields_ordered($field) if $field;
745 # # warn "HTML2MARC=".$record->as_formatted;
746 $record->encoding( 'UTF-8' );
747 # $record->MARC::File::USMARC::update_leader();
752 # warn "MARCkoha2marc";
753 ## This routine most probably will be depreaceated -- it is still used for acqui management
754 ##Returns a MARC record from a hash
755 my ($dbh,$result,$recordtype) = @_;
757 my $record = MARC::Record->new();
758 my $sth2=$dbh->prepare("SELECT marctokoha from koha_attr where tagfield is not null and recordtype=?");
759 $sth2->execute($recordtype);
761 while (($field)=$sth2->fetchrow) {
762 $record=&MARCkoha2marcOnefield($record,$field,$result->{$field},$recordtype) if $result->{$field};
767 # warn "MARCmarc2koha";
768 ##Returns a hash from MARC record
769 my ($dbh,$record,$related_record) = @_;
771 if (!$related_record){$related_record="biblios";}
772 my $sth2=$dbh->prepare("SELECT marctokoha from koha_attr where recordtype like ? and tagfield is not null" );
773 $sth2->execute($related_record);
775 while ($field=$sth2->fetchrow) {
776 $result=&MARCmarc2kohaOneField($field,$record,$result,$related_record);
779 ## we only need the following for biblio data
780 if ($related_record eq "biblios"){
781 # modify copyrightdate to keep only the 1st year found
782 my $temp = $result->{'copyrightdate'};
783 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
785 $result->{'copyrightdate'} = $1;
786 } else { # if no cYYYY, get the 1st date.
787 $temp =~ m/(\d\d\d\d)/;
788 $result->{'copyrightdate'} = $1;
790 # modify publicationyear to keep only the 1st year found
791 $temp = $result->{'publicationyear'};
792 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
794 $result->{'publicationyear'} = $1;
795 } else { # if no cYYYY, get the 1st date.
796 $temp =~ m/(\d\d\d\d)/;
797 $result->{'publicationyear'} = $1;
803 sub MARCkoha2marcOnefield {
804 ##Updates or creates one field in MARC record
805 my ( $record, $kohafieldname, $value,$recordtype ) = @_;
806 my ( $tagfield, $tagsubfield ) = MARCfind_marc_from_kohafield($kohafieldname,$recordtype);
808 my $tag = $record->field($tagfield);
811 if ($value){## We may be trying to delete a subfield value
812 $tag->update( $tagsubfield=> $value );
814 $tag->delete_subfield(code=>$tagsubfield);
816 $record->delete_field($tag);
817 $record->insert_fields_ordered($tag);
819 my $newtag=MARC::Field->new( $tagfield, " ", " ", $tagsubfield => $value);
820 $record->insert_fields_ordered($newtag);
825 $tag->update( $value );
826 $record->delete_field($tag);
827 $record->insert_fields_ordered($tag);
829 $record->delete_field($tag);
832 my $newtag=MARC::Field->new( $tagfield => $value);
833 $record->insert_fields_ordered($newtag);
836 }## $tagfield defined
840 sub MARCmarc2kohaOneField {
841 my ( $kohafield, $record, $result,$recordtype ) = @_;
842 # # warn "kohatable / $kohafield / $result / ";
845 my ( $tagfield, $subfield ) = MARCfind_marc_from_kohafield($kohafield,$recordtype);
847 foreach my $field ( $record->field($tagfield) ) {
848 if ($field->tag()<10) {
849 if ($result->{$kohafield}) {
850 $result->{$kohafield} .= " | ".$field->data();
852 $result->{$kohafield} = $field->data();
855 if ( $field->subfields ) {
856 my @subfields = $field->subfields();
857 foreach my $subfieldcount ( 0 .. $#subfields ) {
858 if ($subfields[$subfieldcount][0] eq $subfield) {
859 if ( $result->{$kohafield} ) {
860 $result->{$kohafield} .= " | " . $subfields[$subfieldcount][1];
863 $result->{$kohafield} = $subfields[$subfieldcount][1];
875 # warn "MARCmodLCindex";
876 my ($dbh,$record)=@_;
878 my ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield("classification","biblios");
879 my ($tagfield2,$tagsubfieldsub) = MARCfind_marc_from_kohafield("subclass","biblios");
880 my $tag=$record->field($tagfield);
882 my ($lcsort)=calculatelc($tag->subfield($tagsubfield)).$tag->subfield($tagsubfieldsub);
884 &MARCkoha2marcOnefield( $record, "lcsort", $lcsort,"biblios");
889 ##########################NEW NEW NEW#############################
891 my ( $dbh, $record, $frameworkcode) = @_;
893 $frameworkcode="" unless $frameworkcode;
894 my $olddata = MARCmarc2koha( $dbh, $record,"biblios" );
895 ## In case reimporting records with biblionumbers keep them
896 if ($olddata->{'biblionumber'}){
897 $biblionumber=NEWmodbiblio( $dbh, $olddata->{'biblionumber'},$record,$frameworkcode );
899 $biblionumber = NEWaddbiblio( $dbh, $record,$frameworkcode );
902 return ( $biblionumber );
909 sub NEWmodbiblioframework {
910 my ($dbh,$biblionumber,$frameworkcode) =@_;
911 my $sth = $dbh->prepare("Update biblio SET frameworkcode=? WHERE biblionumber=$biblionumber");
912 $sth->execute($frameworkcode);
919 my ( $dbh, $biblionumber ) = @_;
920 my $sth=$dbh->prepare("SELECT itemnumber FROM items where biblionumber=?");
922 $sth->execute($biblionumber);
923 while (my $itemnumber =$sth->fetchrow){
924 OLDdelitem($dbh,$itemnumber) ;
927 ZEBRAop($dbh,$biblionumber,"recordDelete","biblioserver");
928 OLDdelbiblio($dbh,$biblionumber) ;
933 my ( $dbh, $record, $biblionumber ) = @_;
934 my $itemtype= MARCfind_itemtype($dbh,$biblionumber);
935 my $item = &MARCmarc2koha( $dbh, $record,"holdings" );
936 ## In case we are re-importing marc records from bulk import do not change itemnumbers
937 if ($item->{itemnumber}){
938 NEWmoditem ( $dbh, $record, $biblionumber, $item->{itemnumber});
940 $item->{'biblionumber'} =$biblionumber;
941 ##Add biblionumber to $record
942 MARCkoha2marcOnefield($record,"biblionumber",$biblionumber,"holdings");
943 my $sth=$dbh->prepare("select notforloan from itemtypes where itemtype='$itemtype'");
945 my $notforloan=$sth->fetchrow;
946 ##Change the notforloan field if $notforloan found
948 $item->{'notforloan'}=$notforloan;
949 &MARCkoha2marcOnefield($record,"notforloan",$notforloan,"holdings");
951 if(!$item->{'dateaccessioned'}||$item->{'dateaccessioned'} eq ''){
953 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
954 localtime(time); $year +=1900; $mon +=1;
955 my $date = "$year-".sprintf ("%0.2d", $mon)."-".sprintf("%0.2d",$mday);
956 $item->{'dateaccessioned'}=$date;
957 &MARCkoha2marcOnefield($record,"dateaccessioned",$date,"holdings");
960 ## Now calculate itempart of cutter
961 my ($cutterextra)=itemcalculator($dbh,$item->{'biblionumber'},$item->{'itemcallnumber'});
962 &MARCkoha2marcOnefield($record,"cutterextra",$cutterextra,"holdings");
964 ##NEU specific add cataloguers cardnumber as well
965 my ($tag,$cardtag)=MARCfind_marc_from_kohafield("circid","holdings");
966 if ($tag && $cardtag){
967 my $me= C4::Context->userenv;
968 my $cataloguer=$me->{'cardnumber'} if ($me);
969 my $newtag= $record->field($tag);
970 $newtag->update($cardtag=>$cataloguer) if ($me);
971 $record->delete_field($newtag);
972 $record->insert_fields_ordered($newtag);
975 my $itemnumber = &OLDnewitems( $dbh, $item->{barcode},$record );
977 # add the item to zebra it will add the biblio as well!!!
978 ZEBRAop( $dbh, $biblionumber,"specialUpdate","biblioserver" );
987 my ( $dbh, $record, $biblionumber, $itemnumber ) = @_;
988 ##Get a hash of this record as well
989 my $item=MARCmarc2koha($dbh,$record,"holdings");
990 ##Add itemnumber incase lost (old bug 090c was lost) --just incase
991 my ( $tagfield, $tagsubfield ) =MARCfind_marc_from_kohafield("itemnumber","holdings");
993 my $old_field = $record->field($tagfield);
995 $newfield = MARC::Field->new($tagfield, $itemnumber);
998 $old_field->update($tagsubfield=>$biblionumber);
999 $newfield=$old_field->clone();
1001 $newfield = MARC::Field->new($tagfield, '', '', "$tagsubfield" => $itemnumber);
1004 # drop old field and create new one...
1006 $record->delete_field($old_field);
1007 $record->insert_fields_ordered($newfield);
1008 ##Add biblionumber incase lost on html
1009 my ( $tagfield, $tagsubfield ) =MARCfind_marc_from_kohafield("biblionumber","holdings");
1011 my $old_field = $record->field($tagfield);
1013 $newfield = MARC::Field->new($tagfield, $biblionumber);
1016 $old_field->update($tagsubfield=>$biblionumber);
1017 $newfield=$old_field->clone();
1019 $newfield = MARC::Field->new($tagfield, '', '', "$tagsubfield" => $biblionumber);
1022 # drop old field and create new one...
1023 $record->delete_field($old_field);
1024 $record->insert_fields_ordered($newfield);
1026 ###NEU specific add cataloguers cardnumber as well
1027 my ($tag,$cardtag)=MARCfind_marc_from_kohafield("circid","holdings");
1028 if ($tag && $cardtag){
1029 my $me= C4::Context->userenv;
1030 my $cataloger=$me->{'cardnumber'} if ($me);
1031 my $oldtag=$record->field($tag);
1033 my $newtag= MARC::Field->new($tag, '', '', $cardtag => $cataloger) if ($me);
1034 $record->insert_fields_ordered($newtag);
1036 $oldtag->update($cardtag=>$cataloger) if ($me);
1037 $record->delete_field($oldtag);
1038 $record->insert_fields_ordered($oldtag);
1041 ## We must add the indexing fields for LC Cutter in MARC record in case it changed
1042 my ($cutterextra)=itemcalculator($dbh,$biblionumber,$item->{'itemcallnumber'});
1043 MARCkoha2marcOnefield($record,"cutterextra",$cutterextra,"holdings");
1044 OLDmoditem( $dbh, $record,$biblionumber,$itemnumber,$item->{barcode} );
1045 ZEBRAop($dbh,$biblionumber,"specialUpdate","biblioserver");
1049 my ( $dbh, $itemnumber ) = @_;
1051 my $sth=$dbh->prepare("SELECT biblionumber from items where itemnumber=?");
1052 $sth->execute($itemnumber);
1053 my $biblionumber=$sth->fetchrow;
1054 OLDdelitem( $dbh, $itemnumber ) ;
1055 ZEBRAop($dbh,$biblionumber,"recordDelete","biblioserver");
1063 my ( $dbh, $record,$frameworkcode ) = @_;
1064 my $sth = $dbh->prepare("Select max(biblionumber) from biblio");
1066 my $data = $sth->fetchrow;
1067 my $biblionumber = $data + 1;
1069 # we must add biblionumber MARC::Record...
1070 my ( $tagfield, $tagsubfield ) =MARCfind_marc_from_kohafield("biblionumber","biblios");
1073 $newfield = MARC::Field->new($tagfield, $biblionumber);
1075 $newfield = MARC::Field->new($tagfield, '', '', "$tagsubfield" => "$biblionumber");
1077 # drop old field and create new one..
1078 $record->delete_field($newfield);
1079 $record->insert_fields_ordered($newfield);
1081 ###NEU specific add cataloguers cardnumber as well
1082 my ($tag,$cardtag)=MARCfind_marc_from_kohafield("indexedby","biblios");
1083 if ($tag && $cardtag){
1084 my $me= C4::Context->userenv;
1085 my $cataloger=$me->{'cardnumber'} if ($me);
1086 my $oldtag=$record->field($tag);
1088 my $newtag= MARC::Field->new($tag, '', '', $cardtag => $cataloger) if ($me);
1089 $record->insert_fields_ordered($newtag);
1091 $oldtag->update($cardtag=>$cataloger) if ($me);
1092 $record->delete_field($oldtag);
1093 $record->insert_fields_ordered($oldtag);
1096 ## We must add the indexing fields for LC in MARC record--TG
1097 &MARCmodLCindex($dbh,$record);
1100 ($tagfield,$tagsubfield)=MARCfind_marc_from_kohafield("itemtype","biblios");
1101 my $itemtype=$record->field($tagfield)->subfield($tagsubfield) if ($record->field($tagfield));
1103 ($tagfield,$tagsubfield)=MARCfind_marc_from_kohafield("isbn","biblios") ;
1104 my $isbn=$record->field($tagfield)->subfield($tagsubfield) if ($record->field($tagfield));
1106 ($tagfield,$tagsubfield)=MARCfind_marc_from_kohafield("issn","biblios") ;
1107 my $issn=$record->field($tagfield)->subfield($tagsubfield) if ($record->field($tagfield));
1108 $sth = $dbh->prepare("insert into biblio set biblionumber = ?, marc = ?, frameworkcode=?, itemtype=?,marcxml=?,title=?,author=?,isbn=?,issn=?" );
1109 $sth->execute( $biblionumber, $record->as_usmarc,$frameworkcode, $itemtype,MARC::File::XML::record( $record ) ,$record->title(),$record->author,$isbn,$issn );
1112 ### Do not add biblio to ZEBRA unless there is an item with it -- depends on system preference defaults to NO
1113 if (C4::Context->preference('AddaloneBiblios')){
1114 ZEBRAop($dbh,$biblionumber,"specialUpdate","biblioserver");
1116 return ($biblionumber);
1120 my ( $dbh, $biblionumber,$record,$frameworkcode ) = @_;
1121 ##Add biblionumber incase lost on html
1122 my ( $tagfield, $tagsubfield ) =MARCfind_marc_from_kohafield("biblionumber","biblios");
1125 $newfield = MARC::Field->new($tagfield, $biblionumber);
1127 $newfield = MARC::Field->new($tagfield, '', '', "$tagsubfield" => $biblionumber);
1129 # drop old field and create new one...
1130 my $old_field = $record->field($tagfield);
1131 $record->delete_field($old_field);
1132 $record->insert_fields_ordered($newfield);
1134 ###NEU specific add cataloguers cardnumber as well
1135 my ($tag,$cardtag)=MARCfind_marc_from_kohafield("indexedby","biblios");
1136 if ($tag && $cardtag){
1137 my $me= C4::Context->userenv;
1138 my $cataloger=$me->{'cardnumber'} if ($me);
1139 my $oldtag=$record->field($tag);
1141 my $newtag= MARC::Field->new($tag, '', '', $cardtag => $cataloger) if ($me);
1142 $record->insert_fields_ordered($newtag);
1144 $oldtag->update($cardtag=>$cataloger) if ($me);
1145 $record->delete_field($oldtag);
1146 $record->insert_fields_ordered($oldtag);
1149 ## We must add the indexing fields for LC in MARC record--TG
1150 MARCmodLCindex($dbh,$record);
1151 OLDmodbiblio ($dbh,$record,$biblionumber,$frameworkcode);
1152 my $ok=ZEBRAop($dbh,$biblionumber,"specialUpdate","biblioserver");
1153 return ($biblionumber);
1158 # OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD
1164 my ( $dbh, $barcode,$record) = @_;
1165 my $sth = $dbh->prepare("SELECT max(itemnumber) from items");
1169 $data = $sth->fetchrow_hashref;
1170 $itemnumber = $data->{'max(itemnumber)'} + 1;
1172 &MARCkoha2marcOnefield( $record, "itemnumber", $itemnumber,"holdings" );
1173 my ($biblionumbertag,$subf)=MARCfind_marc_from_kohafield( "biblionumber","holdings");
1176 if ($biblionumbertag <10){
1177 $biblionumber=$record->field($biblionumbertag)->data();
1179 $biblionumber=$record->field($biblionumbertag)->subfield($subf);
1181 $sth = $dbh->prepare( "Insert into items set itemnumber = ?, biblionumber = ?,barcode = ?,marc=? ,marcxml=?" );
1182 $sth->execute($itemnumber,$biblionumber,$barcode,$record->as_usmarc(),MARC::File::XML::record( $record));
1187 my ( $dbh, $record,$biblionumber,$itemnumber,$barcode ) = @_;
1188 my $sth =$dbh->prepare("replace items set biblionumber=?,marc=?,marcxml=?,barcode=? , itemnumber=?");
1189 $sth->execute($biblionumber,$record->as_usmarc(),MARC::File::XML::record( $record),$barcode,$itemnumber);
1194 my ( $dbh, $itemnumber ) = @_;
1195 my $sth = $dbh->prepare("select * from items where itemnumber=?");
1196 $sth->execute($itemnumber);
1197 if ( my $data = $sth->fetchrow_hashref ) {
1199 my $query = "replace deleteditems set ";
1201 foreach my $temp ( keys %$data ) {
1202 $query .= "$temp = ?,";
1203 push ( @bind, $data->{$temp} );
1206 #replacing the last , by ",?)"
1208 $sth = $dbh->prepare($query);
1209 $sth->execute(@bind);
1211 $sth = $dbh->prepare("Delete from items where itemnumber=?");
1212 $sth->execute($itemnumber);
1219 # modifies the biblio table
1220 my ($dbh,$record,$biblionumber,$frameworkcode) = @_;
1221 if (!$frameworkcode){
1224 my ($tagfield,$tagsubfield)=MARCfind_marc_from_kohafield("itemtype","biblios");
1225 my $itemtype=$record->field($tagfield)->subfield($tagsubfield) if ($record->field($tagfield));
1226 my ($tagfield,$tagsubfield)=MARCfind_marc_from_kohafield("isbn","biblios");
1227 my $isbn=$record->field($tagfield)->subfield($tagsubfield) if ($record->field($tagfield));
1228 my ($tagfield,$tagsubfield)=MARCfind_marc_from_kohafield("issn","biblios");
1229 my $issn=$record->field($tagfield)->subfield($tagsubfield) if ($record->field($tagfield));
1230 $isbn=~ s/(\.|\?|\;|\=|\-|\/|\\|\||\:|\*|\!|\,|\(|\)|\[|\]|\{|\}|\/)//g;
1231 $issn=~ s/(\.|\?|\;|\=|\-|\/|\\|\||\:|\*|\!|\,|\(|\)|\[|\]|\{|\}|\/)//g;
1232 $isbn=~s/^\s+|\s+$//g;
1233 $isbn=substr($isbn,0,13);
1234 my $sth = $dbh->prepare("REPLACE biblio set biblionumber=?,marc=?,marcxml=?,frameworkcode=? ,itemtype=? , title=?,author=?,isbn=?,issn=?" );
1235 $sth->execute( $biblionumber,$record->as_usmarc() ,MARC::File::XML::record( $record), $frameworkcode,$itemtype, $record->title(),$record->author(),$isbn,$issn);
1237 return $biblionumber;
1241 my ( $dbh, $biblionumber ) = @_;
1242 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
1243 $sth->execute($biblionumber);
1244 if ( my $data = $sth->fetchrow_hashref ) {
1246 my $query = "replace deletedbiblio set ";
1248 foreach my $temp ( keys %$data ) {
1249 $query .= "$temp = ?,";
1250 push ( @bind, $data->{$temp} );
1253 #replacing the last , by ",?)"
1255 $sth = $dbh->prepare($query);
1256 $sth->execute(@bind);
1258 $sth = $dbh->prepare("Delete from biblio where biblionumber=?");
1259 $sth->execute($biblionumber);
1274 ##Utility function to write an xml file to disk when the zebra server goes down
1275 my ($dbh,$biblionumber,$record,$folder,$server)=@_;
1276 #my $record = XMLgetbiblio($dbh,$biblionumber);
1278 my $zebradir = C4::Context->zebraconfig($server)->{directory}."/".$folder."/";
1279 my $zebraroot=C4::Context->zebraconfig($server)->{directory};
1280 my $serverbase=C4::Context->config($server);
1281 unless (opendir(DIR, "$zebradir")) {
1282 # warn "$zebradir not found";
1286 my $filename = $zebradir.$biblionumber;
1288 open (OUTPUT,">", $filename.".xml");
1289 print OUTPUT $record;
1296 ### Puts the zebra update in queue writes in zebraserver table
1297 my ($dbh,$biblionumber,$op,$server)=@_;
1300 my $sth=$dbh->prepare("insert into zebraqueue (biblio_auth_number ,server,operation) values(?,?,?)");
1301 $sth->execute($biblionumber,$server,$op);
1307 ###Accepts a $server variable thus we can use it to update biblios, authorities or other zebra dbs
1308 my ($record,$op,$server)=@_;
1315 $record=Encode::encode("UTF-8",$record);
1316 my $shadow=$server."shadow";
1319 $Zconnbiblio[0]=C4::Context->Zconnauth($server);
1321 my $Zpackage = $Zconnbiblio[0]->package();
1322 $Zpackage->option(action => $op);
1323 $Zpackage->option(record => $record);
1325 $Zpackage->send("update");
1329 while (($i = ZOOM::event(\@Zconnbiblio)) != 0) {
1330 $event = $Zconnbiblio[0]->last_event();
1331 last if $event == ZOOM::Event::ZEND;
1333 my($error, $errmsg, $addinfo, $diagset) = $Zconnbiblio[0]->error_x();
1334 if ($error==10007 && $tried<3) {## timeout --another 30 looonng seconds for this update
1335 sleep 1; ## wait a sec!
1338 }elsif ($error==2 && $tried<2) {## timeout --temporary zebra error !whatever that means
1339 sleep 2; ## wait two seconds!
1342 }elsif($error==10004 && $recon==0){##Lost connection -reconnect
1343 sleep 1; ## wait a sec!
1345 $Zpackage->destroy();
1346 $Zconnbiblio[0]->destroy();
1349 # warn "Error-$server $op /errcode:, $error, /MSG:,$errmsg,$addinfo \n";
1350 $Zpackage->destroy();
1351 $Zconnbiblio[0]->destroy();
1352 # ZEBRAopfiles($dbh,$biblionumber,$record,$op,$server);
1355 ## System preference batchMode=1 means wea are bulk importing
1356 ## DO NOT COMMIT while in batchMode for faster operation
1357 my $batchmode=C4::Context->preference('batchMode');
1358 if (C4::Context->$shadow >0 && !$batchmode){
1359 $Zpackage->send('commit');
1360 while (($i = ZOOM::event(\@Zconnbiblio)) != 0) {
1361 $event = $Zconnbiblio[0]->last_event();
1362 last if $event == ZOOM::Event::ZEND;
1364 my($error, $errmsg, $addinfo, $diagset) = $Zconnbiblio[0]->error_x();
1365 if ($error) { ## This is serious ZEBRA server is not updating
1366 $Zpackage->destroy();
1367 $Zconnbiblio[0]->destroy();
1372 $Zpackage->destroy();
1373 $Zconnbiblio[0]->destroy();
1380 my ($dbh,$biblionumber)=@_;
1381 my $biblioxml=XMLgetbiblio($dbh,$biblionumber);
1382 my @itemxml=XMLgetallitems($dbh,$biblionumber);
1383 my $zebraxml=collection_header();
1384 $zebraxml.="<koharecord>";
1385 $zebraxml.=$biblioxml;
1386 $zebraxml.="<holdings>";
1387 foreach my $item(@itemxml){
1388 $zebraxml.=$item if $item;
1390 $zebraxml.="</holdings>";
1391 $zebraxml.="</koharecord>";
1392 $zebraxml.="</kohacollection>";
1396 sub ZEBRA_readyXML_noheader{
1397 my ($dbh,$biblionumber)=@_;
1398 my $biblioxml=XMLgetbiblio($dbh,$biblionumber);
1399 my @itemxml=XMLgetallitems($dbh,$biblionumber);
1400 my $zebraxml="<koharecord>";
1401 $zebraxml.=$biblioxml;
1402 $zebraxml.="<holdings>";
1403 foreach my $item(@itemxml){
1404 $zebraxml.=$item if $item;
1406 $zebraxml.="</holdings>";
1407 $zebraxml.="</koharecord>";
1413 # various utility subs and those not complying to new rules
1418 ## Used in acqui management -- creates the biblio from hash rather than marc-record
1420 my $dbh = C4::Context->dbh;
1421 my $record=MARCkoha2marc($dbh,$biblio,"biblios");
1422 $record->encoding('UTF-8');
1423 my $biblionumber=NEWnewbiblio($dbh,$record);
1424 return ($biblionumber);
1427 ## Used in acqui management -- modifies the biblio from hash rather than marc-record
1429 my $dbh = C4::Context->dbh;
1430 my $record=MARCkoha2marc($dbh,$biblio,"biblios");
1431 my $biblionumber=NEWmodbiblio($dbh,$record,$biblio->{biblionumber});
1432 return ($biblionumber);
1436 ## Used in acqui management -- creates the item from hash rather than marc-record
1437 my ( $item, @barcodes ) = @_;
1438 my $dbh = C4::Context->dbh;
1442 foreach my $barcode (@barcodes) {
1443 $item->{barcode}=$barcode;
1444 my $record=MARCkoha2marc($dbh,$item,"holdings");
1445 my $itemnumber= NEWnewitem($dbh,$record,$item->{biblionumber});
1448 return $itemnumber ;
1455 my $dbh = C4::Context->dbh;
1456 my $query = "select * from itemtypes order by description";
1457 my $sth = $dbh->prepare($query);
1459 # || die "Cannot prepare $query" . $dbh->errstr;
1463 # || die "Cannot execute $query\n" . $sth->errstr;
1464 while ( my $data = $sth->fetchrow_hashref ) {
1465 $results[$count] = $data;
1470 return ( $count, @results );
1471 } # sub getitemtypes
1476 #returns MySQL like fieldnames to emulate searches on sql like fieldnames
1478 ## Either opac or intranet to select appropriate fields
1480 $type="intra" unless $type;
1481 if ($type eq "intranet"){ $type="intra";}
1482 my $dbh = C4::Context->dbh;
1486 my $sth=$dbh->prepare("SELECT * FROM koha_attr where $type=1 order by liblibrarian");
1488 while (my $data=$sth->fetchrow_hashref){
1493 return ($i,@results);
1501 ## Old style ISBN handling should be modified to accept 13 digits
1504 if(substr($isbn, 0, 1) <=7) {
1505 $seg1 = substr($isbn, 0, 1);
1506 } elsif(substr($isbn, 0, 2) <= 94) {
1507 $seg1 = substr($isbn, 0, 2);
1508 } elsif(substr($isbn, 0, 3) <= 995) {
1509 $seg1 = substr($isbn, 0, 3);
1510 } elsif(substr($isbn, 0, 4) <= 9989) {
1511 $seg1 = substr($isbn, 0, 4);
1513 $seg1 = substr($isbn, 0, 5);
1515 my $x = substr($isbn, length($seg1));
1517 if(substr($x, 0, 2) <= 19) {
1518 # if(sTmp2 < 10) sTmp2 = "0" sTmp2;
1519 $seg2 = substr($x, 0, 2);
1520 } elsif(substr($x, 0, 3) <= 699) {
1521 $seg2 = substr($x, 0, 3);
1522 } elsif(substr($x, 0, 4) <= 8399) {
1523 $seg2 = substr($x, 0, 4);
1524 } elsif(substr($x, 0, 5) <= 89999) {
1525 $seg2 = substr($x, 0, 5);
1526 } elsif(substr($x, 0, 6) <= 9499999) {
1527 $seg2 = substr($x, 0, 6);
1529 $seg2 = substr($x, 0, 7);
1531 my $seg3=substr($x,length($seg2));
1532 $seg3=substr($seg3,0,length($seg3)-1) ;
1533 my $seg4 = substr($x, -1, 1);
1534 return "$seg1-$seg2-$seg3-$seg4";
1537 ## Function to create padded LC call number for sorting items with their LC code. Not exported
1538 my ($classification)=@_;
1539 $classification=~s/^\s+|\s+$//g;
1543 for ($i=0; $i<length($classification);$i++){
1544 my $c=(substr($classification,$i,1));
1545 if ($c ge '0' && $c le '9'){
1547 $lc2=substr($classification,$i);
1550 $lc1.=substr($classification,$i,1);
1555 my $other=length($lc1);
1556 if(!$lc1){$other=0;}
1559 for (1..(4-$other)){
1568 ##Find the decimal part of $lc2
1569 my $pos=index($lc2,".");
1570 if ($pos<0){$pos=length($lc2);}
1571 if ($pos>=0 && $pos<5){
1572 ##Pad lc2 with zeros to create a 5digit decimal needed in marc record to sort as numeric
1583 ## Sublimentary function to obtain sorted LC for items. Not exported
1584 my ($dbh,$biblionumber,$callnumber)=@_;
1585 my ($record,$frameworkcode)=MARCgetbiblio($dbh,$biblionumber);
1586 my $biblio=MARCmarc2koha($dbh,$record,$frameworkcode,"biblios");
1588 my $all=$biblio->{classification}." ".$biblio->{subclass};
1589 my $total=length($all);
1590 my $cutterextra=substr($callnumber,$total);
1592 return $cutterextra;
1597 #### This function allows decoding of only title and author out of a MARC record
1598 sub func_title_author {
1599 my ($tagno,$tagdata) = @_;
1600 my ($titlef,$subf)=&MARCfind_marc_from_kohafield("title","biblios");
1601 my ($authf,$subf)=&MARCfind_marc_from_kohafield("author","biblios");
1602 return ($tagno == $titlef || $tagno == $authf);
1607 END { } # module clean-up code here (global destructor)
1613 Koha Developement team <info@koha.org>