3 # Copyright 2000-2002 Katipo Communications
4 # Parts Copyright 2010 Nelsonville Public Library
5 # Parts copyright 2010 BibLibre
7 # This file is part of Koha.
9 # Koha is free software; you can redistribute it and/or modify it under the
10 # terms of the GNU General Public License as published by the Free Software
11 # Foundation; either version 2 of the License, or (at your option) any later
14 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License along
19 # with Koha; if not, write to the Free Software Foundation, Inc.,
20 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #use warnings; FIXME - Bug 2505
27 use URI::Split qw(uri_split);
31 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
61 &GetAuthorisedValueByCode
62 &GetKohaImageurlFromAuthorisedValues
67 &GetNormalizedOCLCNumber
76 memoize('GetAuthorisedValues');
77 memoize('getitemtypeinfo');
81 C4::Koha - Perl Module containing convenience functions for Koha scripts
89 Koha.pm provides many functions for Koha scripts.
97 $slash_date = &slashifyDate($dash_date);
99 Takes a string of the form "DD-MM-YYYY" (or anything separated by
100 dashes), converts it to the form "YYYY/MM/DD", and returns the result.
106 # accepts a date of the form xx-xx-xx[xx] and returns it in the
108 my @dateOut = split( '-', shift );
109 return ("$dateOut[2]/$dateOut[1]/$dateOut[0]");
112 # FIXME.. this should be moved to a MARC-specific module
113 sub subfield_is_koha_internal_p ($) {
116 # We could match on 'lib' and 'tab' (and 'mandatory', & more to come!)
117 # But real MARC subfields are always single-character
118 # so it really is safer just to check the length
120 return length $subfield != 1;
123 =head2 GetSupportName
125 $itemtypename = &GetSupportName($codestring);
127 Returns a string with the name of the itemtype.
133 return if (! $codestring);
135 my $advanced_search_types = C4::Context->preference("AdvancedSearchTypes");
136 if (!$advanced_search_types or $advanced_search_types eq 'itemtypes') {
143 my $sth = C4::Context->dbh->prepare($query);
144 $sth->execute($codestring);
145 ($resultstring)=$sth->fetchrow;
146 return $resultstring;
149 C4::Context->dbh->prepare(
150 "SELECT lib FROM authorised_values WHERE category = ? AND authorised_value = ?"
152 $sth->execute( $advanced_search_types, $codestring );
153 my $data = $sth->fetchrow_hashref;
154 return $$data{'lib'};
158 =head2 GetSupportList
160 $itemtypes = &GetSupportList();
162 Returns an array ref containing informations about Support (since itemtype is rather a circulation code when item-level-itypes is used).
164 build a HTML select with the following code :
166 =head3 in PERL SCRIPT
168 my $itemtypes = GetSupportList();
169 $template->param(itemtypeloop => $itemtypes);
173 <form action='<!-- TMPL_VAR name="script_name" -->' method=post>
174 <select name="itemtype">
175 <option value="">Default</option>
176 <!-- TMPL_LOOP name="itemtypeloop" -->
177 <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>
180 <input type=text name=searchfield value="<!-- TMPL_VAR name="searchfield" -->">
181 <input type="submit" value="OK" class="button">
187 my $advanced_search_types = C4::Context->preference("AdvancedSearchTypes");
188 if (!$advanced_search_types or $advanced_search_types eq 'itemtypes') {
194 my $sth = C4::Context->dbh->prepare($query);
196 return $sth->fetchall_arrayref({});
198 my $advsearchtypes = GetAuthorisedValues($advanced_search_types);
199 my @results= map {{itemtype=>$$_{authorised_value},description=>$$_{lib},imageurl=>$$_{imageurl}}} @$advsearchtypes;
205 $itemtypes = &GetItemTypes();
207 Returns information about existing itemtypes.
209 build a HTML select with the following code :
211 =head3 in PERL SCRIPT
213 my $itemtypes = GetItemTypes;
215 foreach my $thisitemtype (sort keys %$itemtypes) {
216 my $selected = 1 if $thisitemtype eq $itemtype;
217 my %row =(value => $thisitemtype,
218 selected => $selected,
219 description => $itemtypes->{$thisitemtype}->{'description'},
221 push @itemtypesloop, \%row;
223 $template->param(itemtypeloop => \@itemtypesloop);
227 <form action='<!-- TMPL_VAR name="script_name" -->' method=post>
228 <select name="itemtype">
229 <option value="">Default</option>
230 <!-- TMPL_LOOP name="itemtypeloop" -->
231 <option value="<!-- TMPL_VAR name="value" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="description" --></option>
234 <input type=text name=searchfield value="<!-- TMPL_VAR name="searchfield" -->">
235 <input type="submit" value="OK" class="button">
242 # returns a reference to a hash of references to itemtypes...
244 my $dbh = C4::Context->dbh;
249 my $sth = $dbh->prepare($query);
251 while ( my $IT = $sth->fetchrow_hashref ) {
252 $itemtypes{ $IT->{'itemtype'} } = $IT;
254 return ( \%itemtypes );
257 sub get_itemtypeinfos_of {
260 my $placeholders = join( ', ', map { '?' } @itemtypes );
261 my $query = <<"END_SQL";
267 WHERE itemtype IN ( $placeholders )
270 return get_infos_of( $query, 'itemtype', undef, \@itemtypes );
273 # this is temporary until we separate collection codes and item types
277 my $dbh = C4::Context->dbh;
280 "SELECT * FROM authorised_values ORDER BY authorised_value");
282 while ( my $data = $sth->fetchrow_hashref ) {
283 if ( $data->{category} eq "CCODE" ) {
285 $results[$count] = $data;
291 return ( $count, @results );
296 $authtypes = &getauthtypes();
298 Returns information about existing authtypes.
300 build a HTML select with the following code :
302 =head3 in PERL SCRIPT
304 my $authtypes = getauthtypes;
306 foreach my $thisauthtype (keys %$authtypes) {
307 my $selected = 1 if $thisauthtype eq $authtype;
308 my %row =(value => $thisauthtype,
309 selected => $selected,
310 authtypetext => $authtypes->{$thisauthtype}->{'authtypetext'},
312 push @authtypesloop, \%row;
314 $template->param(itemtypeloop => \@itemtypesloop);
318 <form action='<!-- TMPL_VAR name="script_name" -->' method=post>
319 <select name="authtype">
320 <!-- TMPL_LOOP name="authtypeloop" -->
321 <option value="<!-- TMPL_VAR name="value" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="authtypetext" --></option>
324 <input type=text name=searchfield value="<!-- TMPL_VAR name="searchfield" -->">
325 <input type="submit" value="OK" class="button">
333 # returns a reference to a hash of references to authtypes...
335 my $dbh = C4::Context->dbh;
336 my $sth = $dbh->prepare("select * from auth_types order by authtypetext");
338 while ( my $IT = $sth->fetchrow_hashref ) {
339 $authtypes{ $IT->{'authtypecode'} } = $IT;
341 return ( \%authtypes );
345 my ($authtypecode) = @_;
347 # returns a reference to a hash of references to authtypes...
349 my $dbh = C4::Context->dbh;
350 my $sth = $dbh->prepare("select * from auth_types where authtypecode=?");
351 $sth->execute($authtypecode);
352 my $res = $sth->fetchrow_hashref;
358 $frameworks = &getframework();
360 Returns information about existing frameworks
362 build a HTML select with the following code :
364 =head3 in PERL SCRIPT
366 my $frameworks = frameworks();
368 foreach my $thisframework (keys %$frameworks) {
369 my $selected = 1 if $thisframework eq $frameworkcode;
370 my %row =(value => $thisframework,
371 selected => $selected,
372 description => $frameworks->{$thisframework}->{'frameworktext'},
374 push @frameworksloop, \%row;
376 $template->param(frameworkloop => \@frameworksloop);
380 <form action='<!-- TMPL_VAR name="script_name" -->' method=post>
381 <select name="frameworkcode">
382 <option value="">Default</option>
383 <!-- TMPL_LOOP name="frameworkloop" -->
384 <option value="<!-- TMPL_VAR name="value" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="frameworktext" --></option>
387 <input type=text name=searchfield value="<!-- TMPL_VAR name="searchfield" -->">
388 <input type="submit" value="OK" class="button">
395 # returns a reference to a hash of references to branches...
397 my $dbh = C4::Context->dbh;
398 my $sth = $dbh->prepare("select * from biblio_framework");
400 while ( my $IT = $sth->fetchrow_hashref ) {
401 $itemtypes{ $IT->{'frameworkcode'} } = $IT;
403 return ( \%itemtypes );
406 =head2 getframeworkinfo
408 $frameworkinfo = &getframeworkinfo($frameworkcode);
410 Returns information about an frameworkcode.
414 sub getframeworkinfo {
415 my ($frameworkcode) = @_;
416 my $dbh = C4::Context->dbh;
418 $dbh->prepare("select * from biblio_framework where frameworkcode=?");
419 $sth->execute($frameworkcode);
420 my $res = $sth->fetchrow_hashref;
424 =head2 getitemtypeinfo
426 $itemtype = &getitemtype($itemtype);
428 Returns information about an itemtype.
432 sub getitemtypeinfo {
434 my $dbh = C4::Context->dbh;
435 my $sth = $dbh->prepare("select * from itemtypes where itemtype=?");
436 $sth->execute($itemtype);
437 my $res = $sth->fetchrow_hashref;
439 $res->{imageurl} = getitemtypeimagelocation( 'intranet', $res->{imageurl} );
444 =head2 getitemtypeimagedir
446 my $directory = getitemtypeimagedir( 'opac' );
448 pass in 'opac' or 'intranet'. Defaults to 'opac'.
450 returns the full path to the appropriate directory containing images.
454 sub getitemtypeimagedir {
455 my $src = shift || 'opac';
456 if ($src eq 'intranet') {
457 return C4::Context->config('intrahtdocs') . '/' .C4::Context->preference('template') . '/img/itemtypeimg';
459 return C4::Context->config('opachtdocs') . '/' . C4::Context->preference('template') . '/itemtypeimg';
463 sub getitemtypeimagesrc {
464 my $src = shift || 'opac';
465 if ($src eq 'intranet') {
466 return '/intranet-tmpl' . '/' . C4::Context->preference('template') . '/img/itemtypeimg';
468 return '/opac-tmpl' . '/' . C4::Context->preference('template') . '/itemtypeimg';
472 sub getitemtypeimagelocation($$) {
473 my ( $src, $image ) = @_;
475 return '' if ( !$image );
477 my $scheme = ( uri_split( $image ) )[0];
479 return $image if ( $scheme );
481 return getitemtypeimagesrc( $src ) . '/' . $image;
484 =head3 _getImagesFromDirectory
486 Find all of the image files in a directory in the filesystem
488 parameters: a directory name
490 returns: a list of images in that directory.
492 Notes: this does not traverse into subdirectories. See
493 _getSubdirectoryNames for help with that.
494 Images are assumed to be files with .gif or .png file extensions.
495 The image names returned do not have the directory name on them.
499 sub _getImagesFromDirectory {
500 my $directoryname = shift;
501 return unless defined $directoryname;
502 return unless -d $directoryname;
504 if ( opendir ( my $dh, $directoryname ) ) {
505 my @images = grep { /\.(gif|png)$/i } readdir( $dh );
507 @images = sort(@images);
510 warn "unable to opendir $directoryname: $!";
515 =head3 _getSubdirectoryNames
517 Find all of the directories in a directory in the filesystem
519 parameters: a directory name
521 returns: a list of subdirectories in that directory.
523 Notes: this does not traverse into subdirectories. Only the first
524 level of subdirectories are returned.
525 The directory names returned don't have the parent directory name on them.
529 sub _getSubdirectoryNames {
530 my $directoryname = shift;
531 return unless defined $directoryname;
532 return unless -d $directoryname;
534 if ( opendir ( my $dh, $directoryname ) ) {
535 my @directories = grep { -d File::Spec->catfile( $directoryname, $_ ) && ! ( /^\./ ) } readdir( $dh );
539 warn "unable to opendir $directoryname: $!";
546 returns: a listref of hashrefs. Each hash represents another collection of images.
548 { imagesetname => 'npl', # the name of the image set (npl is the original one)
549 images => listref of image hashrefs
552 each image is represented by a hashref like this:
554 { KohaImage => 'npl/image.gif',
555 StaffImageUrl => '/intranet-tmpl/prog/img/itemtypeimg/npl/image.gif',
556 OpacImageURL => '/opac-tmpl/prog/itemtypeimg/npl/image.gif'
557 checked => 0 or 1: was this the image passed to this method?
558 Note: I'd like to remove this somehow.
565 my $checked = $params{'checked'} || '';
567 my $paths = { staff => { filesystem => getitemtypeimagedir('intranet'),
568 url => getitemtypeimagesrc('intranet'),
570 opac => { filesystem => getitemtypeimagedir('opac'),
571 url => getitemtypeimagesrc('opac'),
575 my @imagesets = (); # list of hasrefs of image set data to pass to template
576 my @subdirectories = _getSubdirectoryNames( $paths->{'staff'}{'filesystem'} );
577 warn $paths->{'staff'}{'filesystem'};
578 foreach my $imagesubdir ( @subdirectories ) {
580 my @imagelist = (); # hashrefs of image info
581 my @imagenames = _getImagesFromDirectory( File::Spec->catfile( $paths->{'staff'}{'filesystem'}, $imagesubdir ) );
582 my $imagesetactive = 0;
583 foreach my $thisimage ( @imagenames ) {
585 { KohaImage => "$imagesubdir/$thisimage",
586 StaffImageUrl => join( '/', $paths->{'staff'}{'url'}, $imagesubdir, $thisimage ),
587 OpacImageUrl => join( '/', $paths->{'opac'}{'url'}, $imagesubdir, $thisimage ),
588 checked => "$imagesubdir/$thisimage" eq $checked ? 1 : 0,
591 $imagesetactive = 1 if "$imagesubdir/$thisimage" eq $checked;
593 push @imagesets, { imagesetname => $imagesubdir,
594 imagesetactive => $imagesetactive,
595 images => \@imagelist };
603 $printers = &GetPrinters();
604 @queues = keys %$printers;
606 Returns information about existing printer queues.
608 C<$printers> is a reference-to-hash whose keys are the print queues
609 defined in the printers table of the Koha database. The values are
610 references-to-hash, whose keys are the fields in the printers table.
616 my $dbh = C4::Context->dbh;
617 my $sth = $dbh->prepare("select * from printers");
619 while ( my $printer = $sth->fetchrow_hashref ) {
620 $printers{ $printer->{'printqueue'} } = $printer;
622 return ( \%printers );
627 $printer = GetPrinter( $query, $printers );
631 sub GetPrinter ($$) {
632 my ( $query, $printers ) = @_; # get printer for this query from printers
633 my $printer = $query->param('printer');
634 my %cookie = $query->cookie('userenv');
635 ($printer) || ( $printer = $cookie{'printer'} ) || ( $printer = '' );
636 ( $printers->{$printer} ) || ( $printer = ( keys %$printers )[0] );
642 Returns the number of pages to display in a pagination bar, given the number
643 of items and the number of items per page.
648 my ( $nb_items, $nb_items_per_page ) = @_;
650 return int( ( $nb_items - 1 ) / $nb_items_per_page ) + 1;
655 (@themes) = &getallthemes('opac');
656 (@themes) = &getallthemes('intranet');
658 Returns an array of all available themes.
666 if ( $type eq 'intranet' ) {
667 $htdocs = C4::Context->config('intrahtdocs');
670 $htdocs = C4::Context->config('opachtdocs');
672 opendir D, "$htdocs";
673 my @dirlist = readdir D;
674 foreach my $directory (@dirlist) {
675 -d "$htdocs/$directory/en" and push @themes, $directory;
682 if ( C4::Context->preference("marcflavour") eq "UNIMARC" ) {
685 link_value => 'su-to',
686 label_value => 'Topics',
688 [ '600', '601', '602', '603', '604', '605', '606', '610' ],
692 link_value => 'su-geo',
693 label_value => 'Places',
698 link_value => 'su-ut',
699 label_value => 'Titles',
700 tags => [ '500', '501', '502', '503', '504', ],
705 label_value => 'Authors',
706 tags => [ '700', '701', '702', ],
711 label_value => 'Series',
720 link_value => 'branch',
721 label_value => 'Libraries',
726 push @$facets, $library_facet unless C4::Context->preference("singleBranchMode");
731 link_value => 'su-to',
732 label_value => 'Topics',
738 # link_value => 'su-na',
739 # label_value => 'People and Organizations',
740 # tags => ['600', '610', '611'],
744 link_value => 'su-geo',
745 label_value => 'Places',
750 link_value => 'su-ut',
751 label_value => 'Titles',
757 label_value => 'Authors',
758 tags => [ '100', '110', '700', ],
763 label_value => 'Series',
764 tags => [ '440', '490', ],
770 link_value => 'branch',
771 label_value => 'Libraries',
776 push @$facets, $library_facet unless C4::Context->preference("singleBranchMode");
783 Return a href where a key is associated to a href. You give a query,
784 the name of the key among the fields returned by the query. If you
785 also give as third argument the name of the value, the function
786 returns a href of scalar. The optional 4th argument is an arrayref of
787 items passed to the C<execute()> call. It is designed to bind
788 parameters to any placeholders in your SQL.
797 # generic href of any information on the item, href of href.
798 my $iteminfos_of = get_infos_of($query, 'itemnumber');
799 print $iteminfos_of->{$itemnumber}{barcode};
801 # specific information, href of scalar
802 my $barcode_of_item = get_infos_of($query, 'itemnumber', 'barcode');
803 print $barcode_of_item->{$itemnumber};
808 my ( $query, $key_name, $value_name, $bind_params ) = @_;
810 my $dbh = C4::Context->dbh;
812 my $sth = $dbh->prepare($query);
813 $sth->execute( @$bind_params );
816 while ( my $row = $sth->fetchrow_hashref ) {
817 if ( defined $value_name ) {
818 $infos_of{ $row->{$key_name} } = $row->{$value_name};
821 $infos_of{ $row->{$key_name} } = $row;
829 =head2 get_notforloan_label_of
831 my $notforloan_label_of = get_notforloan_label_of();
833 Each authorised value of notforloan (information available in items and
834 itemtypes) is link to a single label.
836 Returns a href where keys are authorised values and values are corresponding
839 foreach my $authorised_value (keys %{$notforloan_label_of}) {
841 "authorised_value: %s => %s\n",
843 $notforloan_label_of->{$authorised_value}
849 # FIXME - why not use GetAuthorisedValues ??
851 sub get_notforloan_label_of {
852 my $dbh = C4::Context->dbh;
855 SELECT authorised_value
856 FROM marc_subfield_structure
857 WHERE kohafield = \'items.notforloan\'
860 my $sth = $dbh->prepare($query);
862 my ($statuscode) = $sth->fetchrow_array();
867 FROM authorised_values
870 $sth = $dbh->prepare($query);
871 $sth->execute($statuscode);
872 my %notforloan_label_of;
873 while ( my $row = $sth->fetchrow_hashref ) {
874 $notforloan_label_of{ $row->{authorised_value} } = $row->{lib};
878 return \%notforloan_label_of;
881 =head2 displayServers
883 my $servers = displayServers();
884 my $servers = displayServers( $position );
885 my $servers = displayServers( $position, $type );
887 displayServers returns a listref of hashrefs, each containing
888 information about available z3950 servers. Each hashref has a format
892 'checked' => 'checked',
893 'encoding' => 'MARC-8'
895 'id' => 'LIBRARY OF CONGRESS',
899 'value' => 'z3950.loc.gov:7090/',
906 my ( $position, $type ) = @_;
907 my $dbh = C4::Context->dbh;
909 my $strsth = 'SELECT * FROM z3950servers';
914 push @bind_params, $position;
915 push @where_clauses, ' position = ? ';
919 push @bind_params, $type;
920 push @where_clauses, ' type = ? ';
923 # reassemble where clause from where clause pieces
924 if (@where_clauses) {
925 $strsth .= ' WHERE ' . join( ' AND ', @where_clauses );
928 my $rq = $dbh->prepare($strsth);
929 $rq->execute(@bind_params);
930 my @primaryserverloop;
932 while ( my $data = $rq->fetchrow_hashref ) {
933 push @primaryserverloop,
934 { label => $data->{description},
937 value => $data->{host} . ":" . $data->{port} . "/" . $data->{database},
938 encoding => ( $data->{encoding} ? $data->{encoding} : "iso-5426" ),
939 checked => "checked",
940 icon => $data->{icon},
941 zed => $data->{type} eq 'zed',
942 opensearch => $data->{type} eq 'opensearch'
945 return \@primaryserverloop;
949 =head2 GetKohaImageurlFromAuthorisedValues
951 $authhorised_value = GetKohaImageurlFromAuthorisedValues( $category, $authvalcode );
953 Return the first url of the authorised value image represented by $lib.
957 sub GetKohaImageurlFromAuthorisedValues {
958 my ( $category, $lib ) = @_;
959 my $dbh = C4::Context->dbh;
960 my $sth = $dbh->prepare("SELECT imageurl FROM authorised_values WHERE category=? AND lib =?");
961 $sth->execute( $category, $lib );
962 while ( my $data = $sth->fetchrow_hashref ) {
963 return $data->{'imageurl'};
967 =head2 GetAuthValCode
969 $authvalcode = GetAuthValCode($kohafield,$frameworkcode);
974 my ($kohafield,$fwcode) = @_;
975 my $dbh = C4::Context->dbh;
976 $fwcode='' unless $fwcode;
977 my $sth = $dbh->prepare('select authorised_value from marc_subfield_structure where kohafield=? and frameworkcode=?');
978 $sth->execute($kohafield,$fwcode);
979 my ($authvalcode) = $sth->fetchrow_array;
983 =head2 GetAuthValCodeFromField
985 $authvalcode = GetAuthValCodeFromField($field,$subfield,$frameworkcode);
987 C<$subfield> can be undefined
991 sub GetAuthValCodeFromField {
992 my ($field,$subfield,$fwcode) = @_;
993 my $dbh = C4::Context->dbh;
994 $fwcode='' unless $fwcode;
996 if (defined $subfield) {
997 $sth = $dbh->prepare('select authorised_value from marc_subfield_structure where tagfield=? and tagsubfield=? and frameworkcode=?');
998 $sth->execute($field,$subfield,$fwcode);
1000 $sth = $dbh->prepare('select authorised_value from marc_tag_structure where tagfield=? and frameworkcode=?');
1001 $sth->execute($field,$fwcode);
1003 my ($authvalcode) = $sth->fetchrow_array;
1004 return $authvalcode;
1007 =head2 GetAuthorisedValues
1009 $authvalues = GetAuthorisedValues([$category], [$selected]);
1011 This function returns all authorised values from the'authorised_value' table in a reference to array of hashrefs.
1013 C<$category> returns authorised values for just one category (optional).
1015 C<$opac> If set to a true value, displays OPAC descriptions rather than normal ones when they exist.
1019 sub GetAuthorisedValues {
1020 my ($category,$selected,$opac) = @_;
1022 my $dbh = C4::Context->dbh;
1023 my $query = "SELECT * FROM authorised_values";
1024 $query .= " WHERE category = '" . $category . "'" if $category;
1025 $query .= " ORDER BY category, lib, lib_opac";
1026 my $sth = $dbh->prepare($query);
1028 while (my $data=$sth->fetchrow_hashref) {
1029 if ($selected && $selected eq $data->{'authorised_value'} ) {
1030 $data->{'selected'} = 1;
1032 if ($opac && $data->{'lib_opac'}) {
1033 $data->{'lib'} = $data->{'lib_opac'};
1035 push @results, $data;
1037 #my $data = $sth->fetchall_arrayref({});
1038 return \@results; #$data;
1041 =head2 GetAuthorisedValueCategories
1043 $auth_categories = GetAuthorisedValueCategories();
1045 Return an arrayref of all of the available authorised
1050 sub GetAuthorisedValueCategories {
1051 my $dbh = C4::Context->dbh;
1052 my $sth = $dbh->prepare("SELECT DISTINCT category FROM authorised_values ORDER BY category");
1055 while (defined (my $category = $sth->fetchrow_array) ) {
1056 push @results, $category;
1061 =head2 GetAuthorisedValueByCode
1063 $authhorised_value = GetAuthorisedValueByCode( $category, $authvalcode );
1065 Return the lib attribute from authorised_values from the row identified
1066 by the passed category and code
1070 sub GetAuthorisedValueByCode {
1071 my ( $category, $authvalcode ) = @_;
1073 my $dbh = C4::Context->dbh;
1074 my $sth = $dbh->prepare("SELECT lib FROM authorised_values WHERE category=? AND authorised_value =?");
1075 $sth->execute( $category, $authvalcode );
1076 while ( my $data = $sth->fetchrow_hashref ) {
1077 return $data->{'lib'};
1081 =head2 GetKohaAuthorisedValues
1083 Takes $kohafield, $fwcode as parameters.
1085 If $opac parameter is set to a true value, displays OPAC descriptions rather than normal ones when they exist.
1087 Returns hashref of Code => description
1089 Returns undef if no authorised value category is defined for the kohafield.
1093 sub GetKohaAuthorisedValues {
1094 my ($kohafield,$fwcode,$opac) = @_;
1095 $fwcode='' unless $fwcode;
1097 my $dbh = C4::Context->dbh;
1098 my $avcode = GetAuthValCode($kohafield,$fwcode);
1100 my $sth = $dbh->prepare("select authorised_value, lib, lib_opac from authorised_values where category=? ");
1101 $sth->execute($avcode);
1102 while ( my ($val, $lib, $lib_opac) = $sth->fetchrow_array ) {
1103 $values{$val} = ($opac && $lib_opac) ? $lib_opac : $lib;
1111 =head2 GetKohaAuthorisedValuesFromField
1113 Takes $field, $subfield, $fwcode as parameters.
1115 If $opac parameter is set to a true value, displays OPAC descriptions rather than normal ones when they exist.
1116 $subfield can be undefined
1118 Returns hashref of Code => description
1120 Returns undef if no authorised value category is defined for the given field and subfield
1124 sub GetKohaAuthorisedValuesFromField {
1125 my ($field, $subfield, $fwcode,$opac) = @_;
1126 $fwcode='' unless $fwcode;
1128 my $dbh = C4::Context->dbh;
1129 my $avcode = GetAuthValCodeFromField($field, $subfield, $fwcode);
1131 my $sth = $dbh->prepare("select authorised_value, lib, lib_opac from authorised_values where category=? ");
1132 $sth->execute($avcode);
1133 while ( my ($val, $lib, $lib_opac) = $sth->fetchrow_array ) {
1134 $values{$val} = ($opac && $lib_opac) ? $lib_opac : $lib;
1144 my $escaped_string = C4::Koha::xml_escape($string);
1146 Convert &, <, >, ', and " in a string to XML entities
1152 return '' unless defined $str;
1153 $str =~ s/&/&/g;
1156 $str =~ s/'/'/g;
1157 $str =~ s/"/"/g;
1161 =head2 GetKohaAuthorisedValueLib
1163 Takes $category, $authorised_value as parameters.
1165 If $opac parameter is set to a true value, displays OPAC descriptions rather than normal ones when they exist.
1167 Returns authorised value description
1171 sub GetKohaAuthorisedValueLib {
1172 my ($category,$authorised_value,$opac) = @_;
1174 my $dbh = C4::Context->dbh;
1175 my $sth = $dbh->prepare("select lib, lib_opac from authorised_values where category=? and authorised_value=?");
1176 $sth->execute($category,$authorised_value);
1177 my $data = $sth->fetchrow_hashref;
1178 $value = ($opac && $$data{'lib_opac'}) ? $$data{'lib_opac'} : $$data{'lib'};
1182 =head2 display_marc_indicators
1184 my $display_form = C4::Koha::display_marc_indicators($field);
1186 C<$field> is a MARC::Field object
1188 Generate a display form of the indicators of a variable
1189 MARC field, replacing any blanks with '#'.
1193 sub display_marc_indicators {
1195 my $indicators = '';
1196 if ($field->tag() >= 10) {
1197 $indicators = $field->indicator(1) . $field->indicator(2);
1198 $indicators =~ s/ /#/g;
1203 sub GetNormalizedUPC {
1204 my ($record,$marcflavour) = @_;
1207 if ($marcflavour eq 'UNIMARC') {
1208 @fields = $record->field('072');
1209 foreach my $field (@fields) {
1210 my $upc = _normalize_match_point($field->subfield('a'));
1217 else { # assume marc21 if not unimarc
1218 @fields = $record->field('024');
1219 foreach my $field (@fields) {
1220 my $indicator = $field->indicator(1);
1221 my $upc = _normalize_match_point($field->subfield('a'));
1222 if ($indicator == 1 and $upc ne '') {
1229 # Normalizes and returns the first valid ISBN found in the record
1230 # ISBN13 are converted into ISBN10. This is required to get Amazon cover book.
1231 sub GetNormalizedISBN {
1232 my ($isbn,$record,$marcflavour) = @_;
1235 # Koha attempts to store multiple ISBNs in biblioitems.isbn, separated by " | "
1236 # anything after " | " should be removed, along with the delimiter
1237 $isbn =~ s/(.*)( \| )(.*)/$1/;
1238 return _isbn_cleanup($isbn);
1240 return undef unless $record;
1242 if ($marcflavour eq 'UNIMARC') {
1243 @fields = $record->field('010');
1244 foreach my $field (@fields) {
1245 my $isbn = $field->subfield('a');
1247 return _isbn_cleanup($isbn);
1253 else { # assume marc21 if not unimarc
1254 @fields = $record->field('020');
1255 foreach my $field (@fields) {
1256 $isbn = $field->subfield('a');
1258 return _isbn_cleanup($isbn);
1266 sub GetNormalizedEAN {
1267 my ($record,$marcflavour) = @_;
1270 if ($marcflavour eq 'UNIMARC') {
1271 @fields = $record->field('073');
1272 foreach my $field (@fields) {
1273 $ean = _normalize_match_point($field->subfield('a'));
1279 else { # assume marc21 if not unimarc
1280 @fields = $record->field('024');
1281 foreach my $field (@fields) {
1282 my $indicator = $field->indicator(1);
1283 $ean = _normalize_match_point($field->subfield('a'));
1284 if ($indicator == 3 and $ean ne '') {
1290 sub GetNormalizedOCLCNumber {
1291 my ($record,$marcflavour) = @_;
1294 if ($marcflavour eq 'UNIMARC') {
1295 # TODO: add UNIMARC fields
1297 else { # assume marc21 if not unimarc
1298 @fields = $record->field('035');
1299 foreach my $field (@fields) {
1300 $oclc = $field->subfield('a');
1301 if ($oclc =~ /OCoLC/) {
1302 $oclc =~ s/\(OCoLC\)//;
1311 sub _normalize_match_point {
1312 my $match_point = shift;
1313 (my $normalized_match_point) = $match_point =~ /([\d-]*[X]*)/;
1314 $normalized_match_point =~ s/-//g;
1316 return $normalized_match_point;
1320 my $isbn = Business::ISBN->new( $_[0] );
1322 $isbn = $isbn->as_isbn10 if $isbn->type eq 'ISBN13';
1323 if (defined $isbn) {
1324 return $isbn->as_string([]);