3 # Copyright 2000-2002 Katipo Communications
4 # Parts Copyright 2010 Nelsonville Public Library
6 # This file is part of Koha.
8 # Koha is free software; you can redistribute it and/or modify it under the
9 # terms of the GNU General Public License as published by the Free Software
10 # Foundation; either version 2 of the License, or (at your option) any later
13 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
14 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License along
18 # with Koha; if not, write to the Free Software Foundation, Inc.,
19 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #use warnings; FIXME - Bug 2505
26 use URI
::Split
qw(uri_split);
30 use vars
qw($VERSION @ISA @EXPORT $DEBUG);
39 &subfield_is_koha_internal_p
40 &GetPrinters &GetPrinter
41 &GetItemTypes &getitemtypeinfo
43 &GetSupportName &GetSupportList
45 &getframeworks &getframeworkinfo
46 &getauthtypes &getauthtype
52 &get_notforloan_label_of
55 &getitemtypeimagelocation
57 &GetAuthorisedValueCategories
58 &GetKohaAuthorisedValues
59 &GetKohaAuthorisedValuesFromField
60 &GetKohaAuthorisedValueLib
65 &GetNormalizedOCLCNumber
74 memoize
('GetAuthorisedValues');
78 C4::Koha - Perl Module containing convenience functions for Koha scripts
86 Koha.pm provides many functions for Koha scripts.
94 $slash_date = &slashifyDate($dash_date);
96 Takes a string of the form "DD-MM-YYYY" (or anything separated by
97 dashes), converts it to the form "YYYY/MM/DD", and returns the result.
103 # accepts a date of the form xx-xx-xx[xx] and returns it in the
105 my @dateOut = split( '-', shift );
106 return ("$dateOut[2]/$dateOut[1]/$dateOut[0]");
112 my $string = DisplayISBN( $isbn );
118 if (length ($isbn)<13){
120 if ( substr( $isbn, 0, 1 ) <= 7 ) {
121 $seg1 = substr( $isbn, 0, 1 );
123 elsif ( substr( $isbn, 0, 2 ) <= 94 ) {
124 $seg1 = substr( $isbn, 0, 2 );
126 elsif ( substr( $isbn, 0, 3 ) <= 995 ) {
127 $seg1 = substr( $isbn, 0, 3 );
129 elsif ( substr( $isbn, 0, 4 ) <= 9989 ) {
130 $seg1 = substr( $isbn, 0, 4 );
133 $seg1 = substr( $isbn, 0, 5 );
135 my $x = substr( $isbn, length($seg1) );
137 if ( substr( $x, 0, 2 ) <= 19 ) {
139 # if(sTmp2 < 10) sTmp2 = "0" sTmp2;
140 $seg2 = substr( $x, 0, 2 );
142 elsif ( substr( $x, 0, 3 ) <= 699 ) {
143 $seg2 = substr( $x, 0, 3 );
145 elsif ( substr( $x, 0, 4 ) <= 8399 ) {
146 $seg2 = substr( $x, 0, 4 );
148 elsif ( substr( $x, 0, 5 ) <= 89999 ) {
149 $seg2 = substr( $x, 0, 5 );
151 elsif ( substr( $x, 0, 6 ) <= 9499999 ) {
152 $seg2 = substr( $x, 0, 6 );
155 $seg2 = substr( $x, 0, 7 );
157 my $seg3 = substr( $x, length($seg2) );
158 $seg3 = substr( $seg3, 0, length($seg3) - 1 );
159 my $seg4 = substr( $x, -1, 1 );
160 return "$seg1-$seg2-$seg3-$seg4";
163 $seg1 = substr( $isbn, 0, 3 );
165 if ( substr( $isbn, 3, 1 ) <= 7 ) {
166 $seg2 = substr( $isbn, 3, 1 );
168 elsif ( substr( $isbn, 3, 2 ) <= 94 ) {
169 $seg2 = substr( $isbn, 3, 2 );
171 elsif ( substr( $isbn, 3, 3 ) <= 995 ) {
172 $seg2 = substr( $isbn, 3, 3 );
174 elsif ( substr( $isbn, 3, 4 ) <= 9989 ) {
175 $seg2 = substr( $isbn, 3, 4 );
178 $seg2 = substr( $isbn, 3, 5 );
180 my $x = substr( $isbn, length($seg2) +3);
182 if ( substr( $x, 0, 2 ) <= 19 ) {
184 # if(sTmp2 < 10) sTmp2 = "0" sTmp2;
185 $seg3 = substr( $x, 0, 2 );
187 elsif ( substr( $x, 0, 3 ) <= 699 ) {
188 $seg3 = substr( $x, 0, 3 );
190 elsif ( substr( $x, 0, 4 ) <= 8399 ) {
191 $seg3 = substr( $x, 0, 4 );
193 elsif ( substr( $x, 0, 5 ) <= 89999 ) {
194 $seg3 = substr( $x, 0, 5 );
196 elsif ( substr( $x, 0, 6 ) <= 9499999 ) {
197 $seg3 = substr( $x, 0, 6 );
200 $seg3 = substr( $x, 0, 7 );
202 my $seg4 = substr( $x, length($seg3) );
203 $seg4 = substr( $seg4, 0, length($seg4) - 1 );
204 my $seg5 = substr( $x, -1, 1 );
205 return "$seg1-$seg2-$seg3-$seg4-$seg5";
209 # FIXME.. this should be moved to a MARC-specific module
210 sub subfield_is_koha_internal_p
($) {
213 # We could match on 'lib' and 'tab' (and 'mandatory', & more to come!)
214 # But real MARC subfields are always single-character
215 # so it really is safer just to check the length
217 return length $subfield != 1;
220 =head2 GetSupportName
222 $itemtypename = &GetSupportName($codestring);
224 Returns a string with the name of the itemtype.
230 return if (! $codestring);
232 my $advanced_search_types = C4
::Context
->preference("AdvancedSearchTypes");
233 if (!$advanced_search_types or $advanced_search_types eq 'itemtypes') {
240 my $sth = C4
::Context
->dbh->prepare($query);
241 $sth->execute($codestring);
242 ($resultstring)=$sth->fetchrow;
243 return $resultstring;
246 C4
::Context
->dbh->prepare(
247 "SELECT lib FROM authorised_values WHERE category = ? AND authorised_value = ?"
249 $sth->execute( $advanced_search_types, $codestring );
250 my $data = $sth->fetchrow_hashref;
251 return $$data{'lib'};
255 =head2 GetSupportList
257 $itemtypes = &GetSupportList();
259 Returns an array ref containing informations about Support (since itemtype is rather a circulation code when item-level-itypes is used).
261 build a HTML select with the following code :
263 =head3 in PERL SCRIPT
265 my $itemtypes = GetSupportList();
266 $template->param(itemtypeloop => $itemtypes);
270 <form action='<!-- TMPL_VAR name="script_name" -->' method=post>
271 <select name="itemtype">
272 <option value="">Default</option>
273 <!-- TMPL_LOOP name="itemtypeloop" -->
274 <option value="<!-- TMPL_VAR name="itemtype" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->> <!--TMPL_IF Name="imageurl"--><img alt="<!-- TMPL_VAR name="description" -->" src="<!--TMPL_VAR Name="imageurl"-->><!--TMPL_ELSE-->"<!-- TMPL_VAR name="description" --><!--/TMPL_IF--></option>
277 <input type=text name=searchfield value="<!-- TMPL_VAR name="searchfield" -->">
278 <input type="submit" value="OK" class="button">
284 my $advanced_search_types = C4
::Context
->preference("AdvancedSearchTypes");
285 if (!$advanced_search_types or $advanced_search_types eq 'itemtypes') {
291 my $sth = C4
::Context
->dbh->prepare($query);
293 return $sth->fetchall_arrayref({});
295 my $advsearchtypes = GetAuthorisedValues
($advanced_search_types);
296 my @results= map {{itemtype
=>$$_{authorised_value
},description
=>$$_{lib
},imageurl
=>$$_{imageurl
}}} @
$advsearchtypes;
302 $itemtypes = &GetItemTypes();
304 Returns information about existing itemtypes.
306 build a HTML select with the following code :
308 =head3 in PERL SCRIPT
310 my $itemtypes = GetItemTypes;
312 foreach my $thisitemtype (sort keys %$itemtypes) {
313 my $selected = 1 if $thisitemtype eq $itemtype;
314 my %row =(value => $thisitemtype,
315 selected => $selected,
316 description => $itemtypes->{$thisitemtype}->{'description'},
318 push @itemtypesloop, \%row;
320 $template->param(itemtypeloop => \@itemtypesloop);
324 <form action='<!-- TMPL_VAR name="script_name" -->' method=post>
325 <select name="itemtype">
326 <option value="">Default</option>
327 <!-- TMPL_LOOP name="itemtypeloop" -->
328 <option value="<!-- TMPL_VAR name="value" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="description" --></option>
331 <input type=text name=searchfield value="<!-- TMPL_VAR name="searchfield" -->">
332 <input type="submit" value="OK" class="button">
339 # returns a reference to a hash of references to itemtypes...
341 my $dbh = C4
::Context
->dbh;
346 my $sth = $dbh->prepare($query);
348 while ( my $IT = $sth->fetchrow_hashref ) {
349 $itemtypes{ $IT->{'itemtype'} } = $IT;
351 return ( \
%itemtypes );
354 sub get_itemtypeinfos_of
{
357 my $placeholders = join( ', ', map { '?' } @itemtypes );
358 my $query = <<"END_SQL";
364 WHERE itemtype IN ( $placeholders )
367 return get_infos_of( $query, 'itemtype', undef, \@itemtypes );
370 # this is temporary until we separate collection codes and item types
374 my $dbh = C4::Context->dbh;
377 "SELECT * FROM authorised_values ORDER BY authorised_value");
379 while ( my $data = $sth->fetchrow_hashref ) {
380 if ( $data->{category} eq "CCODE" ) {
382 $results[$count] = $data;
388 return ( $count, @results );
393 $authtypes = &getauthtypes();
395 Returns information about existing authtypes.
397 build a HTML select with the following code :
399 =head3 in PERL SCRIPT
401 my $authtypes = getauthtypes;
403 foreach my $thisauthtype (keys %$authtypes) {
404 my $selected = 1 if $thisauthtype eq $authtype;
405 my %row =(value => $thisauthtype,
406 selected => $selected,
407 authtypetext => $authtypes->{$thisauthtype}->{'authtypetext'},
409 push @authtypesloop, \%row;
411 $template->param(itemtypeloop => \@itemtypesloop);
415 <form action='<!-- TMPL_VAR name="script_name" -->' method=post>
416 <select name="authtype">
417 <!-- TMPL_LOOP name="authtypeloop" -->
418 <option value="<!-- TMPL_VAR name="value" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="authtypetext" --></option>
421 <input type=text name=searchfield value="<!-- TMPL_VAR name="searchfield" -->">
422 <input type="submit" value="OK" class="button">
430 # returns a reference to a hash of references to authtypes...
432 my $dbh = C4::Context->dbh;
433 my $sth = $dbh->prepare("select * from auth_types order by authtypetext");
435 while ( my $IT = $sth->fetchrow_hashref ) {
436 $authtypes{ $IT->{'authtypecode'} } = $IT;
438 return ( \%authtypes );
442 my ($authtypecode) = @_;
444 # returns a reference to a hash of references to authtypes...
446 my $dbh = C4::Context->dbh;
447 my $sth = $dbh->prepare("select * from auth_types where authtypecode=?");
448 $sth->execute($authtypecode);
449 my $res = $sth->fetchrow_hashref;
455 $frameworks = &getframework();
457 Returns information about existing frameworks
459 build a HTML select with the following code :
461 =head3 in PERL SCRIPT
463 my $frameworks = frameworks();
465 foreach my $thisframework (keys %$frameworks) {
466 my $selected = 1 if $thisframework eq $frameworkcode;
467 my %row =(value => $thisframework,
468 selected => $selected,
469 description => $frameworks->{$thisframework}->{'frameworktext'},
471 push @frameworksloop, \%row;
473 $template->param(frameworkloop => \@frameworksloop);
477 <form action='<!-- TMPL_VAR name="script_name" -->' method=post>
478 <select name="frameworkcode">
479 <option value="">Default</option>
480 <!-- TMPL_LOOP name="frameworkloop" -->
481 <option value="<!-- TMPL_VAR name="value" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="frameworktext" --></option>
484 <input type=text name=searchfield value="<!-- TMPL_VAR name="searchfield" -->">
485 <input type="submit" value="OK" class="button">
492 # returns a reference to a hash of references to branches...
494 my $dbh = C4::Context->dbh;
495 my $sth = $dbh->prepare("select * from biblio_framework");
497 while ( my $IT = $sth->fetchrow_hashref ) {
498 $itemtypes{ $IT->{'frameworkcode'} } = $IT;
500 return ( \%itemtypes );
503 =head2 getframeworkinfo
505 $frameworkinfo = &getframeworkinfo($frameworkcode);
507 Returns information about an frameworkcode.
511 sub getframeworkinfo {
512 my ($frameworkcode) = @_;
513 my $dbh = C4::Context->dbh;
515 $dbh->prepare("select * from biblio_framework where frameworkcode=?");
516 $sth->execute($frameworkcode);
517 my $res = $sth->fetchrow_hashref;
521 =head2 getitemtypeinfo
523 $itemtype = &getitemtype($itemtype);
525 Returns information about an itemtype.
529 sub getitemtypeinfo {
531 my $dbh = C4::Context->dbh;
532 my $sth = $dbh->prepare("select * from itemtypes where itemtype=?");
533 $sth->execute($itemtype);
534 my $res = $sth->fetchrow_hashref;
536 $res->{imageurl} = getitemtypeimagelocation( 'intranet', $res->{imageurl} );
541 =head2 getitemtypeimagedir
543 my $directory = getitemtypeimagedir( 'opac' );
545 pass in 'opac' or 'intranet'. Defaults to 'opac'.
547 returns the full path to the appropriate directory containing images.
551 sub getitemtypeimagedir {
552 my $src = shift || 'opac';
553 if ($src eq 'intranet') {
554 return C4::Context->config('intrahtdocs') . '/' .C4::Context->preference('template') . '/img/itemtypeimg';
556 return C4::Context->config('opachtdocs') . '/' . C4::Context->preference('template') . '/itemtypeimg';
560 sub getitemtypeimagesrc {
561 my $src = shift || 'opac';
562 if ($src eq 'intranet') {
563 return '/intranet-tmpl' . '/' . C4::Context->preference('template') . '/img/itemtypeimg';
565 return '/opac-tmpl' . '/' . C4::Context->preference('template') . '/itemtypeimg';
569 sub getitemtypeimagelocation($$) {
570 my ( $src, $image ) = @_;
572 return '' if ( !$image );
574 my $scheme = ( uri_split( $image ) )[0];
576 return $image if ( $scheme );
578 return getitemtypeimagesrc( $src ) . '/' . $image;
581 =head3 _getImagesFromDirectory
583 Find all of the image files in a directory in the filesystem
585 parameters: a directory name
587 returns: a list of images in that directory.
589 Notes: this does not traverse into subdirectories. See
590 _getSubdirectoryNames for help with that.
591 Images are assumed to be files with .gif or .png file extensions.
592 The image names returned do not have the directory name on them.
596 sub _getImagesFromDirectory {
597 my $directoryname = shift;
598 return unless defined $directoryname;
599 return unless -d $directoryname;
601 if ( opendir ( my $dh, $directoryname ) ) {
602 my @images = grep { /\.(gif|png)$/i } readdir( $dh );
604 @images = sort(@images);
607 warn "unable to opendir $directoryname: $!";
612 =head3 _getSubdirectoryNames
614 Find all of the directories in a directory in the filesystem
616 parameters: a directory name
618 returns: a list of subdirectories in that directory.
620 Notes: this does not traverse into subdirectories. Only the first
621 level of subdirectories are returned.
622 The directory names returned don't have the parent directory name on them.
626 sub _getSubdirectoryNames {
627 my $directoryname = shift;
628 return unless defined $directoryname;
629 return unless -d $directoryname;
631 if ( opendir ( my $dh, $directoryname ) ) {
632 my @directories = grep { -d File::Spec->catfile( $directoryname, $_ ) && ! ( /^\./ ) } readdir( $dh );
636 warn "unable to opendir $directoryname: $!";
643 returns: a listref of hashrefs. Each hash represents another collection of images.
645 { imagesetname => 'npl', # the name of the image set (npl is the original one)
646 images => listref of image hashrefs
649 each image is represented by a hashref like this:
651 { KohaImage => 'npl/image.gif',
652 StaffImageUrl => '/intranet-tmpl/prog/img/itemtypeimg/npl/image.gif',
653 OpacImageURL => '/opac-tmpl/prog/itemtypeimg/npl/image.gif'
654 checked => 0 or 1: was this the image passed to this method?
655 Note: I'd like to remove this somehow.
662 my $checked = $params{'checked'} || '';
664 my $paths = { staff => { filesystem => getitemtypeimagedir('intranet'),
665 url => getitemtypeimagesrc('intranet'),
667 opac => { filesystem => getitemtypeimagedir('opac'),
668 url => getitemtypeimagesrc('opac'),
672 my @imagesets = (); # list of hasrefs of image set data to pass to template
673 my @subdirectories = _getSubdirectoryNames( $paths->{'staff'}{'filesystem'} );
675 foreach my $imagesubdir ( @subdirectories ) {
676 my @imagelist = (); # hashrefs of image info
677 my @imagenames = _getImagesFromDirectory( File::Spec->catfile( $paths->{'staff'}{'filesystem'}, $imagesubdir ) );
678 my $imagesetactive = 0;
679 foreach my $thisimage ( @imagenames ) {
681 { KohaImage => "$imagesubdir/$thisimage",
682 StaffImageUrl => join( '/', $paths->{'staff'}{'url'}, $imagesubdir, $thisimage ),
683 OpacImageUrl => join( '/', $paths->{'opac'}{'url'}, $imagesubdir, $thisimage ),
684 checked => "$imagesubdir/$thisimage" eq $checked ? 1 : 0,
687 $imagesetactive = 1 if "$imagesubdir/$thisimage" eq $checked;
689 push @imagesets, { imagesetname => $imagesubdir,
690 imagesetactive => $imagesetactive,
691 images => \@imagelist };
699 $printers = &GetPrinters();
700 @queues = keys %$printers;
702 Returns information about existing printer queues.
704 C<$printers> is a reference-to-hash whose keys are the print queues
705 defined in the printers table of the Koha database. The values are
706 references-to-hash, whose keys are the fields in the printers table.
712 my $dbh = C4::Context->dbh;
713 my $sth = $dbh->prepare("select * from printers");
715 while ( my $printer = $sth->fetchrow_hashref ) {
716 $printers{ $printer->{'printqueue'} } = $printer;
718 return ( \%printers );
723 $printer = GetPrinter( $query, $printers );
727 sub GetPrinter ($$) {
728 my ( $query, $printers ) = @_; # get printer for this query from printers
729 my $printer = $query->param('printer');
730 my %cookie = $query->cookie('userenv');
731 ($printer) || ( $printer = $cookie{'printer'} ) || ( $printer = '' );
732 ( $printers->{$printer} ) || ( $printer = ( keys %$printers )[0] );
738 Returns the number of pages to display in a pagination bar, given the number
739 of items and the number of items per page.
744 my ( $nb_items, $nb_items_per_page ) = @_;
746 return int( ( $nb_items - 1 ) / $nb_items_per_page ) + 1;
751 (@themes) = &getallthemes('opac');
752 (@themes) = &getallthemes('intranet');
754 Returns an array of all available themes.
762 if ( $type eq 'intranet' ) {
763 $htdocs = C4::Context->config('intrahtdocs');
766 $htdocs = C4::Context->config('opachtdocs');
768 opendir D, "$htdocs";
769 my @dirlist = readdir D;
770 foreach my $directory (@dirlist) {
771 -d "$htdocs/$directory/en" and push @themes, $directory;
778 if ( C4::Context->preference("marcflavour") eq "UNIMARC" ) {
781 link_value => 'su-to',
782 label_value => 'Topics',
784 [ '600', '601', '602', '603', '604', '605', '606', '610' ],
788 link_value => 'su-geo',
789 label_value => 'Places',
794 link_value => 'su-ut',
795 label_value => 'Titles',
796 tags => [ '500', '501', '502', '503', '504', ],
801 label_value => 'Authors',
802 tags => [ '700', '701', '702', ],
807 label_value => 'Series',
816 link_value => 'branch',
817 label_value => 'Libraries',
822 push @$facets, $library_facet unless C4::Context->preference("singleBranchMode");
827 link_value => 'su-to',
828 label_value => 'Topics',
834 # link_value => 'su-na',
835 # label_value => 'People and Organizations',
836 # tags => ['600', '610', '611'],
840 link_value => 'su-geo',
841 label_value => 'Places',
846 link_value => 'su-ut',
847 label_value => 'Titles',
853 label_value => 'Authors',
854 tags => [ '100', '110', '700', ],
859 label_value => 'Series',
860 tags => [ '440', '490', ],
866 link_value => 'branch',
867 label_value => 'Libraries',
872 push @$facets, $library_facet unless C4::Context->preference("singleBranchMode");
879 Return a href where a key is associated to a href. You give a query,
880 the name of the key among the fields returned by the query. If you
881 also give as third argument the name of the value, the function
882 returns a href of scalar. The optional 4th argument is an arrayref of
883 items passed to the C<execute()> call. It is designed to bind
884 parameters to any placeholders in your SQL.
893 # generic href of any information on the item, href of href.
894 my $iteminfos_of = get_infos_of($query, 'itemnumber');
895 print $iteminfos_of->{$itemnumber}{barcode};
897 # specific information, href of scalar
898 my $barcode_of_item = get_infos_of($query, 'itemnumber', 'barcode');
899 print $barcode_of_item->{$itemnumber};
904 my ( $query, $key_name, $value_name, $bind_params ) = @_;
906 my $dbh = C4::Context->dbh;
908 my $sth = $dbh->prepare($query);
909 $sth->execute( @$bind_params );
912 while ( my $row = $sth->fetchrow_hashref ) {
913 if ( defined $value_name ) {
914 $infos_of{ $row->{$key_name} } = $row->{$value_name};
917 $infos_of{ $row->{$key_name} } = $row;
925 =head2 get_notforloan_label_of
927 my $notforloan_label_of = get_notforloan_label_of();
929 Each authorised value of notforloan (information available in items and
930 itemtypes) is link to a single label.
932 Returns a href where keys are authorised values and values are corresponding
935 foreach my $authorised_value (keys %{$notforloan_label_of}) {
937 "authorised_value: %s => %s\n",
939 $notforloan_label_of->{$authorised_value}
945 # FIXME - why not use GetAuthorisedValues ??
947 sub get_notforloan_label_of {
948 my $dbh = C4::Context->dbh;
951 SELECT authorised_value
952 FROM marc_subfield_structure
953 WHERE kohafield = \'items.notforloan\'
956 my $sth = $dbh->prepare($query);
958 my ($statuscode) = $sth->fetchrow_array();
963 FROM authorised_values
966 $sth = $dbh->prepare($query);
967 $sth->execute($statuscode);
968 my %notforloan_label_of;
969 while ( my $row = $sth->fetchrow_hashref ) {
970 $notforloan_label_of{ $row->{authorised_value} } = $row->{lib};
974 return \%notforloan_label_of;
977 =head2 displayServers
979 my $servers = displayServers();
980 my $servers = displayServers( $position );
981 my $servers = displayServers( $position, $type );
983 displayServers returns a listref of hashrefs, each containing
984 information about available z3950 servers. Each hashref has a format
988 'checked' => 'checked',
989 'encoding' => 'MARC-8'
991 'id' => 'LIBRARY OF CONGRESS',
995 'value' => 'z3950.loc.gov:7090/',
1001 sub displayServers {
1002 my ( $position, $type ) = @_;
1003 my $dbh = C4::Context->dbh;
1005 my $strsth = 'SELECT * FROM z3950servers';
1010 push @bind_params, $position;
1011 push @where_clauses, ' position = ? ';
1015 push @bind_params, $type;
1016 push @where_clauses, ' type = ? ';
1019 # reassemble where clause from where clause pieces
1020 if (@where_clauses) {
1021 $strsth .= ' WHERE ' . join( ' AND ', @where_clauses );
1024 my $rq = $dbh->prepare($strsth);
1025 $rq->execute(@bind_params);
1026 my @primaryserverloop;
1028 while ( my $data = $rq->fetchrow_hashref ) {
1029 push @primaryserverloop,
1030 { label => $data->{description},
1031 id => $data->{name},
1033 value => $data->{host} . ":" . $data->{port} . "/" . $data->{database},
1034 encoding => ( $data->{encoding} ? $data->{encoding} : "iso-5426" ),
1035 checked => "checked",
1036 icon => $data->{icon},
1037 zed => $data->{type} eq 'zed',
1038 opensearch => $data->{type} eq 'opensearch'
1041 return \@primaryserverloop;
1044 =head2 GetAuthValCode
1046 $authvalcode = GetAuthValCode($kohafield,$frameworkcode);
1050 sub GetAuthValCode {
1051 my ($kohafield,$fwcode) = @_;
1052 my $dbh = C4::Context->dbh;
1053 $fwcode='' unless $fwcode;
1054 my $sth = $dbh->prepare('select authorised_value from marc_subfield_structure where kohafield=? and frameworkcode=?');
1055 $sth->execute($kohafield,$fwcode);
1056 my ($authvalcode) = $sth->fetchrow_array;
1057 return $authvalcode;
1060 =head2 GetAuthValCodeFromField
1062 $authvalcode = GetAuthValCodeFromField($field,$subfield,$frameworkcode);
1064 C<$subfield> can be undefined
1068 sub GetAuthValCodeFromField {
1069 my ($field,$subfield,$fwcode) = @_;
1070 my $dbh = C4::Context->dbh;
1071 $fwcode='' unless $fwcode;
1073 if (defined $subfield) {
1074 $sth = $dbh->prepare('select authorised_value from marc_subfield_structure where tagfield=? and tagsubfield=? and frameworkcode=?');
1075 $sth->execute($field,$subfield,$fwcode);
1077 $sth = $dbh->prepare('select authorised_value from marc_tag_structure where tagfield=? and frameworkcode=?');
1078 $sth->execute($field,$fwcode);
1080 my ($authvalcode) = $sth->fetchrow_array;
1081 return $authvalcode;
1084 =head2 GetAuthorisedValues
1086 $authvalues = GetAuthorisedValues([$category], [$selected]);
1088 This function returns all authorised values from the'authorised_value' table in a reference to array of hashrefs.
1090 C<$category> returns authorised values for just one category (optional).
1092 C<$opac> If set to a true value, displays OPAC descriptions rather than normal ones when they exist.
1096 sub GetAuthorisedValues {
1097 my ($category,$selected,$opac) = @_;
1099 my $dbh = C4::Context->dbh;
1100 my $query = "SELECT * FROM authorised_values";
1101 $query .= " WHERE category = '" . $category . "'" if $category;
1102 $query .= " ORDER BY category, lib, lib_opac";
1103 my $sth = $dbh->prepare($query);
1105 while (my $data=$sth->fetchrow_hashref) {
1106 if ($selected && $selected eq $data->{'authorised_value'} ) {
1107 $data->{'selected'} = 1;
1109 if ($opac && $data->{'lib_opac'}) {
1110 $data->{'lib'} = $data->{'lib_opac'};
1112 push @results, $data;
1114 #my $data = $sth->fetchall_arrayref({});
1115 return \@results; #$data;
1118 =head2 GetAuthorisedValueCategories
1120 $auth_categories = GetAuthorisedValueCategories();
1122 Return an arrayref of all of the available authorised
1127 sub GetAuthorisedValueCategories {
1128 my $dbh = C4::Context->dbh;
1129 my $sth = $dbh->prepare("SELECT DISTINCT category FROM authorised_values ORDER BY category");
1132 while (my $category = $sth->fetchrow_array) {
1133 push @results, $category;
1138 =head2 GetKohaAuthorisedValues
1140 Takes $kohafield, $fwcode as parameters.
1142 If $opac parameter is set to a true value, displays OPAC descriptions rather than normal ones when they exist.
1144 Returns hashref of Code => description
1146 Returns undef if no authorised value category is defined for the kohafield.
1150 sub GetKohaAuthorisedValues {
1151 my ($kohafield,$fwcode,$opac) = @_;
1152 $fwcode='' unless $fwcode;
1154 my $dbh = C4::Context->dbh;
1155 my $avcode = GetAuthValCode($kohafield,$fwcode);
1157 my $sth = $dbh->prepare("select authorised_value, lib, lib_opac from authorised_values where category=? ");
1158 $sth->execute($avcode);
1159 while ( my ($val, $lib, $lib_opac) = $sth->fetchrow_array ) {
1160 $values{$val} = ($opac && $lib_opac) ? $lib_opac : $lib;
1168 =head2 GetKohaAuthorisedValuesFromField
1170 Takes $field, $subfield, $fwcode as parameters.
1172 If $opac parameter is set to a true value, displays OPAC descriptions rather than normal ones when they exist.
1173 $subfield can be undefined
1175 Returns hashref of Code => description
1177 Returns undef if no authorised value category is defined for the given field and subfield
1181 sub GetKohaAuthorisedValuesFromField {
1182 my ($field, $subfield, $fwcode,$opac) = @_;
1183 $fwcode='' unless $fwcode;
1185 my $dbh = C4::Context->dbh;
1186 my $avcode = GetAuthValCodeFromField($field, $subfield, $fwcode);
1188 my $sth = $dbh->prepare("select authorised_value, lib, lib_opac from authorised_values where category=? ");
1189 $sth->execute($avcode);
1190 while ( my ($val, $lib, $lib_opac) = $sth->fetchrow_array ) {
1191 $values{$val} = ($opac && $lib_opac) ? $lib_opac : $lib;
1201 my $escaped_string = C4::Koha::xml_escape($string);
1203 Convert &, <, >, ', and " in a string to XML entities
1209 return '' unless defined $str;
1210 $str =~ s/&/&/g;
1213 $str =~ s/'/'/g;
1214 $str =~ s/"/"/g;
1218 =head2 GetKohaAuthorisedValueLib
1220 Takes $category, $authorised_value as parameters.
1222 If $opac parameter is set to a true value, displays OPAC descriptions rather than normal ones when they exist.
1224 Returns authorised value description
1228 sub GetKohaAuthorisedValueLib {
1229 my ($category,$authorised_value,$opac) = @_;
1231 my $dbh = C4::Context->dbh;
1232 my $sth = $dbh->prepare("select lib, lib_opac from authorised_values where category=? and authorised_value=?");
1233 $sth->execute($category,$authorised_value);
1234 my $data = $sth->fetchrow_hashref;
1235 $value = ($opac && $$data{'lib_opac'}) ? $$data{'lib_opac'} : $$data{'lib'};
1239 =head2 display_marc_indicators
1241 my $display_form = C4::Koha::display_marc_indicators($field);
1243 C<$field> is a MARC::Field object
1245 Generate a display form of the indicators of a variable
1246 MARC field, replacing any blanks with '#'.
1250 sub display_marc_indicators {
1252 my $indicators = '';
1253 if ($field->tag() >= 10) {
1254 $indicators = $field->indicator(1) . $field->indicator(2);
1255 $indicators =~ s/ /#/g;
1260 sub GetNormalizedUPC {
1261 my ($record,$marcflavour) = @_;
1264 if ($marcflavour eq 'MARC21') {
1265 @fields = $record->field('024');
1266 foreach my $field (@fields) {
1267 my $indicator = $field->indicator(1);
1268 my $upc = _normalize_match_point($field->subfield('a'));
1269 if ($indicator == 1 and $upc ne '') {
1274 else { # assume unimarc if not marc21
1275 @fields = $record->field('072');
1276 foreach my $field (@fields) {
1277 my $upc = _normalize_match_point($field->subfield('a'));
1285 # Normalizes and returns the first valid ISBN found in the record
1286 # ISBN13 are converted into ISBN10. This is required to get Amazon cover book.
1287 sub GetNormalizedISBN {
1288 my ($isbn,$record,$marcflavour) = @_;
1291 # Koha attempts to store multiple ISBNs in biblioitems.isbn, separated by " | "
1292 # anything after " | " should be removed, along with the delimiter
1293 $isbn =~ s/(.*)( \| )(.*)/$1/;
1294 return _isbn_cleanup($isbn);
1296 return undef unless $record;
1298 if ($marcflavour eq 'MARC21') {
1299 @fields = $record->field('020');
1300 foreach my $field (@fields) {
1301 $isbn = $field->subfield('a');
1303 return _isbn_cleanup($isbn);
1309 else { # assume unimarc if not marc21
1310 @fields = $record->field('010');
1311 foreach my $field (@fields) {
1312 my $isbn = $field->subfield('a');
1314 return _isbn_cleanup($isbn);
1323 sub GetNormalizedEAN {
1324 my ($record,$marcflavour) = @_;
1327 if ($marcflavour eq 'MARC21') {
1328 @fields = $record->field('024');
1329 foreach my $field (@fields) {
1330 my $indicator = $field->indicator(1);
1331 $ean = _normalize_match_point($field->subfield('a'));
1332 if ($indicator == 3 and $ean ne '') {
1337 else { # assume unimarc if not marc21
1338 @fields = $record->field('073');
1339 foreach my $field (@fields) {
1340 $ean = _normalize_match_point($field->subfield('a'));
1347 sub GetNormalizedOCLCNumber {
1348 my ($record,$marcflavour) = @_;
1351 if ($marcflavour eq 'MARC21') {
1352 @fields = $record->field('035');
1353 foreach my $field (@fields) {
1354 $oclc = $field->subfield('a');
1355 if ($oclc =~ /OCoLC/) {
1356 $oclc =~ s/\(OCoLC\)//;
1363 else { # TODO: add UNIMARC fields
1367 sub _normalize_match_point {
1368 my $match_point = shift;
1369 (my $normalized_match_point) = $match_point =~ /([\d-]*[X]*)/;
1370 $normalized_match_point =~ s/-//g;
1372 return $normalized_match_point;
1376 my $isbn = Business::ISBN->new( $_[0] );
1378 $isbn = $isbn->as_isbn10 if $isbn->type eq 'ISBN13';
1379 if (defined $isbn) {
1380 return $isbn->as_string([]);