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 C4
::Branch
qw(GetBranchesCount);
29 use Koha
::DateUtils
qw(dt_from_string);
30 use DateTime
::Format
::MySQL
;
32 use autouse
'Data::Dumper' => qw(Dumper);
33 use DBI
qw(:sql_types);
35 use vars
qw($VERSION @ISA @EXPORT @EXPORT_OK $DEBUG);
38 $VERSION = 3.07.00.049;
43 &subfield_is_koha_internal_p
44 &GetPrinters &GetPrinter
45 &GetItemTypes &getitemtypeinfo
46 &GetSupportName &GetSupportList
48 &getframeworks &getframeworkinfo
50 &getauthtypes &getauthtype
56 &get_notforloan_label_of
59 &getitemtypeimagelocation
61 &GetAuthorisedValueCategories
62 &IsAuthorisedValueCategory
63 &GetKohaAuthorisedValues
64 &GetKohaAuthorisedValuesFromField
65 &GetKohaAuthorisedValueLib
66 &GetAuthorisedValueByCode
67 &GetKohaImageurlFromAuthorisedValues
73 &GetNormalizedOCLCNumber
83 @EXPORT_OK = qw( GetDailyQuote );
88 C4::Koha - Perl Module containing convenience functions for Koha scripts
96 Koha.pm provides many functions for Koha scripts.
104 $slash_date = &slashifyDate($dash_date);
106 Takes a string of the form "DD-MM-YYYY" (or anything separated by
107 dashes), converts it to the form "YYYY/MM/DD", and returns the result.
113 # accepts a date of the form xx-xx-xx[xx] and returns it in the
115 my @dateOut = split( '-', shift );
116 return ("$dateOut[2]/$dateOut[1]/$dateOut[0]");
119 # FIXME.. this should be moved to a MARC-specific module
120 sub subfield_is_koha_internal_p
{
123 # We could match on 'lib' and 'tab' (and 'mandatory', & more to come!)
124 # But real MARC subfields are always single-character
125 # so it really is safer just to check the length
127 return length $subfield != 1;
130 =head2 GetSupportName
132 $itemtypename = &GetSupportName($codestring);
134 Returns a string with the name of the itemtype.
140 return if (! $codestring);
142 my $advanced_search_types = C4
::Context
->preference("AdvancedSearchTypes");
143 if (!$advanced_search_types or $advanced_search_types eq 'itemtypes') {
150 my $sth = C4
::Context
->dbh->prepare($query);
151 $sth->execute($codestring);
152 ($resultstring)=$sth->fetchrow;
153 return $resultstring;
156 C4
::Context
->dbh->prepare(
157 "SELECT lib FROM authorised_values WHERE category = ? AND authorised_value = ?"
159 $sth->execute( $advanced_search_types, $codestring );
160 my $data = $sth->fetchrow_hashref;
161 return $$data{'lib'};
165 =head2 GetSupportList
167 $itemtypes = &GetSupportList();
169 Returns an array ref containing informations about Support (since itemtype is rather a circulation code when item-level-itypes is used).
171 build a HTML select with the following code :
173 =head3 in PERL SCRIPT
175 my $itemtypes = GetSupportList();
176 $template->param(itemtypeloop => $itemtypes);
180 <select name="itemtype" id="itemtype">
181 <option value=""></option>
182 [% FOREACH itemtypeloo IN itemtypeloop %]
183 [% IF ( itemtypeloo.selected ) %]
184 <option value="[% itemtypeloo.itemtype %]" selected="selected">[% itemtypeloo.description %]</option>
186 <option value="[% itemtypeloo.itemtype %]">[% itemtypeloo.description %]</option>
194 my $advanced_search_types = C4
::Context
->preference("AdvancedSearchTypes");
195 if (!$advanced_search_types or $advanced_search_types =~ /itemtypes/) {
201 my $sth = C4
::Context
->dbh->prepare($query);
203 return $sth->fetchall_arrayref({});
205 my $advsearchtypes = GetAuthorisedValues
($advanced_search_types);
206 my @results= map {{itemtype
=>$$_{authorised_value
},description
=>$$_{lib
},imageurl
=>$$_{imageurl
}}} @
$advsearchtypes;
212 $itemtypes = &GetItemTypes( style => $style );
214 Returns information about existing itemtypes.
217 style: either 'array' or 'hash', defaults to 'hash'.
218 'array' returns an arrayref,
219 'hash' return a hashref with the itemtype value as the key
221 build a HTML select with the following code :
223 =head3 in PERL SCRIPT
225 my $itemtypes = GetItemTypes;
227 foreach my $thisitemtype (sort keys %$itemtypes) {
228 my $selected = 1 if $thisitemtype eq $itemtype;
229 my %row =(value => $thisitemtype,
230 selected => $selected,
231 description => $itemtypes->{$thisitemtype}->{'description'},
233 push @itemtypesloop, \%row;
235 $template->param(itemtypeloop => \@itemtypesloop);
239 <form action='<!-- TMPL_VAR name="script_name" -->' method=post>
240 <select name="itemtype">
241 <option value="">Default</option>
242 <!-- TMPL_LOOP name="itemtypeloop" -->
243 <option value="<!-- TMPL_VAR name="value" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="description" --></option>
246 <input type=text name=searchfield value="<!-- TMPL_VAR name="searchfield" -->">
247 <input type="submit" value="OK" class="button">
254 my $style = defined( $params{'style'} ) ?
$params{'style'} : 'hash';
256 # returns a reference to a hash of references to itemtypes...
258 my $dbh = C4
::Context
->dbh;
263 my $sth = $dbh->prepare($query);
266 if ( $style eq 'hash' ) {
267 while ( my $IT = $sth->fetchrow_hashref ) {
268 $itemtypes{ $IT->{'itemtype'} } = $IT;
270 return ( \
%itemtypes );
272 return $sth->fetchall_arrayref({});
276 sub get_itemtypeinfos_of
{
279 my $placeholders = join( ', ', map { '?' } @itemtypes );
280 my $query = <<"END_SQL";
286 WHERE itemtype IN ( $placeholders )
289 return get_infos_of( $query, 'itemtype', undef, \@itemtypes );
294 $authtypes = &getauthtypes();
296 Returns information about existing authtypes.
298 build a HTML select with the following code :
300 =head3 in PERL SCRIPT
302 my $authtypes = getauthtypes;
304 foreach my $thisauthtype (keys %$authtypes) {
305 my $selected = 1 if $thisauthtype eq $authtype;
306 my %row =(value => $thisauthtype,
307 selected => $selected,
308 authtypetext => $authtypes->{$thisauthtype}->{'authtypetext'},
310 push @authtypesloop, \%row;
312 $template->param(itemtypeloop => \@itemtypesloop);
316 <form action='<!-- TMPL_VAR name="script_name" -->' method=post>
317 <select name="authtype">
318 <!-- TMPL_LOOP name="authtypeloop" -->
319 <option value="<!-- TMPL_VAR name="value" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="authtypetext" --></option>
322 <input type=text name=searchfield value="<!-- TMPL_VAR name="searchfield" -->">
323 <input type="submit" value="OK" class="button">
331 # returns a reference to a hash of references to authtypes...
333 my $dbh = C4::Context->dbh;
334 my $sth = $dbh->prepare("select * from auth_types order by authtypetext");
336 while ( my $IT = $sth->fetchrow_hashref ) {
337 $authtypes{ $IT->{'authtypecode'} } = $IT;
339 return ( \%authtypes );
343 my ($authtypecode) = @_;
345 # returns a reference to a hash of references to authtypes...
347 my $dbh = C4::Context->dbh;
348 my $sth = $dbh->prepare("select * from auth_types where authtypecode=?");
349 $sth->execute($authtypecode);
350 my $res = $sth->fetchrow_hashref;
356 $frameworks = &getframework();
358 Returns information about existing frameworks
360 build a HTML select with the following code :
362 =head3 in PERL SCRIPT
364 my $frameworks = getframeworks();
366 foreach my $thisframework (keys %$frameworks) {
367 my $selected = 1 if $thisframework eq $frameworkcode;
369 value => $thisframework,
370 selected => $selected,
371 description => $frameworks->{$thisframework}->{'frameworktext'},
373 push @frameworksloop, \%row;
375 $template->param(frameworkloop => \@frameworksloop);
379 <form action="[% script_name %] method=post>
380 <select name="frameworkcode">
381 <option value="">Default</option>
382 [% FOREACH framework IN frameworkloop %]
383 [% IF ( framework.selected ) %]
384 <option value="[% framework.value %]" selected="selected">[% framework.description %]</option>
386 <option value="[% framework.value %]">[% framework.description %]</option>
390 <input type
=text name
=searchfield value
="[% searchfield %]">
391 <input type
="submit" value
="OK" class="button">
398 # returns a reference to a hash of references to branches...
400 my $dbh = C4
::Context
->dbh;
401 my $sth = $dbh->prepare("select * from biblio_framework");
403 while ( my $IT = $sth->fetchrow_hashref ) {
404 $itemtypes{ $IT->{'frameworkcode'} } = $IT;
406 return ( \
%itemtypes );
409 =head2 GetFrameworksLoop
411 $frameworks = GetFrameworksLoop( $frameworkcode );
413 Returns the loop suggested on getframework(), but ordered by framework description.
415 build a HTML select with the following code :
417 =head3 in PERL SCRIPT
419 $template->param( frameworkloop => GetFrameworksLoop( $frameworkcode ) );
423 Same as getframework()
425 <form action="[% script_name %] method=post>
426 <select name="frameworkcode">
427 <option value="">Default</option>
428 [% FOREACH framework IN frameworkloop %]
429 [% IF ( framework.selected ) %]
430 <option value="[% framework.value %]" selected="selected">[% framework.description %]</option>
432 <option value="[% framework.value %]">[% framework.description %]</option>
436 <input type=text name=searchfield value="[% searchfield %]">
437 <input type="submit" value="OK" class="button">
442 sub GetFrameworksLoop
{
443 my $frameworkcode = shift;
444 my $frameworks = getframeworks
();
446 foreach my $thisframework (sort { uc($frameworks->{$a}->{'frameworktext'}) cmp uc($frameworks->{$b}->{'frameworktext'}) } keys %$frameworks) {
447 my $selected = ( $thisframework eq $frameworkcode ) ?
1 : undef;
449 value
=> $thisframework,
450 selected
=> $selected,
451 description
=> $frameworks->{$thisframework}->{'frameworktext'},
453 push @frameworkloop, \
%row;
455 return \
@frameworkloop;
458 =head2 getframeworkinfo
460 $frameworkinfo = &getframeworkinfo($frameworkcode);
462 Returns information about an frameworkcode.
466 sub getframeworkinfo
{
467 my ($frameworkcode) = @_;
468 my $dbh = C4
::Context
->dbh;
470 $dbh->prepare("select * from biblio_framework where frameworkcode=?");
471 $sth->execute($frameworkcode);
472 my $res = $sth->fetchrow_hashref;
476 =head2 getitemtypeinfo
478 $itemtype = &getitemtypeinfo($itemtype, [$interface]);
480 Returns information about an itemtype. The optional $interface argument
481 sets which interface ('opac' or 'intranet') to return the imageurl for.
482 Defaults to intranet.
486 sub getitemtypeinfo
{
487 my ($itemtype, $interface) = @_;
488 my $dbh = C4
::Context
->dbh;
489 my $sth = $dbh->prepare("select * from itemtypes where itemtype=?");
490 $sth->execute($itemtype);
491 my $res = $sth->fetchrow_hashref;
493 $res->{imageurl
} = getitemtypeimagelocation
( ( ( defined $interface && $interface eq 'opac' ) ?
'opac' : 'intranet' ), $res->{imageurl
} );
498 =head2 getitemtypeimagedir
500 my $directory = getitemtypeimagedir( 'opac' );
502 pass in 'opac' or 'intranet'. Defaults to 'opac'.
504 returns the full path to the appropriate directory containing images.
508 sub getitemtypeimagedir
{
509 my $src = shift || 'opac';
510 if ($src eq 'intranet') {
511 return C4
::Context
->config('intrahtdocs') . '/' .C4
::Context
->preference('template') . '/img/itemtypeimg';
513 return C4
::Context
->config('opachtdocs') . '/' . C4
::Context
->preference('opacthemes') . '/itemtypeimg';
517 sub getitemtypeimagesrc
{
518 my $src = shift || 'opac';
519 if ($src eq 'intranet') {
520 return '/intranet-tmpl' . '/' . C4
::Context
->preference('template') . '/img/itemtypeimg';
522 return '/opac-tmpl' . '/' . C4
::Context
->preference('opacthemes') . '/itemtypeimg';
526 sub getitemtypeimagelocation
{
527 my ( $src, $image ) = @_;
529 return '' if ( !$image );
532 my $scheme = ( URI
::Split
::uri_split
( $image ) )[0];
534 return $image if ( $scheme );
536 return getitemtypeimagesrc
( $src ) . '/' . $image;
539 =head3 _getImagesFromDirectory
541 Find all of the image files in a directory in the filesystem
543 parameters: a directory name
545 returns: a list of images in that directory.
547 Notes: this does not traverse into subdirectories. See
548 _getSubdirectoryNames for help with that.
549 Images are assumed to be files with .gif or .png file extensions.
550 The image names returned do not have the directory name on them.
554 sub _getImagesFromDirectory
{
555 my $directoryname = shift;
556 return unless defined $directoryname;
557 return unless -d
$directoryname;
559 if ( opendir ( my $dh, $directoryname ) ) {
560 my @images = grep { /\.(gif|png)$/i } readdir( $dh );
562 @images = sort(@images);
565 warn "unable to opendir $directoryname: $!";
570 =head3 _getSubdirectoryNames
572 Find all of the directories in a directory in the filesystem
574 parameters: a directory name
576 returns: a list of subdirectories in that directory.
578 Notes: this does not traverse into subdirectories. Only the first
579 level of subdirectories are returned.
580 The directory names returned don't have the parent directory name on them.
584 sub _getSubdirectoryNames
{
585 my $directoryname = shift;
586 return unless defined $directoryname;
587 return unless -d
$directoryname;
589 if ( opendir ( my $dh, $directoryname ) ) {
590 my @directories = grep { -d File
::Spec
->catfile( $directoryname, $_ ) && ! ( /^\./ ) } readdir( $dh );
594 warn "unable to opendir $directoryname: $!";
601 returns: a listref of hashrefs. Each hash represents another collection of images.
603 { imagesetname => 'npl', # the name of the image set (npl is the original one)
604 images => listref of image hashrefs
607 each image is represented by a hashref like this:
609 { KohaImage => 'npl/image.gif',
610 StaffImageUrl => '/intranet-tmpl/prog/img/itemtypeimg/npl/image.gif',
611 OpacImageURL => '/opac-tmpl/prog/itemtypeimg/npl/image.gif'
612 checked => 0 or 1: was this the image passed to this method?
613 Note: I'd like to remove this somehow.
620 my $checked = $params{'checked'} || '';
622 my $paths = { staff
=> { filesystem
=> getitemtypeimagedir
('intranet'),
623 url
=> getitemtypeimagesrc
('intranet'),
625 opac
=> { filesystem
=> getitemtypeimagedir
('opac'),
626 url
=> getitemtypeimagesrc
('opac'),
630 my @imagesets = (); # list of hasrefs of image set data to pass to template
631 my @subdirectories = _getSubdirectoryNames
( $paths->{'staff'}{'filesystem'} );
632 foreach my $imagesubdir ( @subdirectories ) {
633 warn $imagesubdir if $DEBUG;
634 my @imagelist = (); # hashrefs of image info
635 my @imagenames = _getImagesFromDirectory
( File
::Spec
->catfile( $paths->{'staff'}{'filesystem'}, $imagesubdir ) );
636 my $imagesetactive = 0;
637 foreach my $thisimage ( @imagenames ) {
639 { KohaImage
=> "$imagesubdir/$thisimage",
640 StaffImageUrl
=> join( '/', $paths->{'staff'}{'url'}, $imagesubdir, $thisimage ),
641 OpacImageUrl
=> join( '/', $paths->{'opac'}{'url'}, $imagesubdir, $thisimage ),
642 checked
=> "$imagesubdir/$thisimage" eq $checked ?
1 : 0,
645 $imagesetactive = 1 if "$imagesubdir/$thisimage" eq $checked;
647 push @imagesets, { imagesetname
=> $imagesubdir,
648 imagesetactive
=> $imagesetactive,
649 images
=> \
@imagelist };
657 $printers = &GetPrinters();
658 @queues = keys %$printers;
660 Returns information about existing printer queues.
662 C<$printers> is a reference-to-hash whose keys are the print queues
663 defined in the printers table of the Koha database. The values are
664 references-to-hash, whose keys are the fields in the printers table.
670 my $dbh = C4
::Context
->dbh;
671 my $sth = $dbh->prepare("select * from printers");
673 while ( my $printer = $sth->fetchrow_hashref ) {
674 $printers{ $printer->{'printqueue'} } = $printer;
676 return ( \
%printers );
681 $printer = GetPrinter( $query, $printers );
686 my ( $query, $printers ) = @_; # get printer for this query from printers
687 my $printer = $query->param('printer');
688 my %cookie = $query->cookie('userenv');
689 ($printer) || ( $printer = $cookie{'printer'} ) || ( $printer = '' );
690 ( $printers->{$printer} ) || ( $printer = ( keys %$printers )[0] );
696 Returns the number of pages to display in a pagination bar, given the number
697 of items and the number of items per page.
702 my ( $nb_items, $nb_items_per_page ) = @_;
704 return int( ( $nb_items - 1 ) / $nb_items_per_page ) + 1;
709 (@themes) = &getallthemes('opac');
710 (@themes) = &getallthemes('intranet');
712 Returns an array of all available themes.
720 if ( $type eq 'intranet' ) {
721 $htdocs = C4
::Context
->config('intrahtdocs');
724 $htdocs = C4
::Context
->config('opachtdocs');
726 opendir D
, "$htdocs";
727 my @dirlist = readdir D
;
728 foreach my $directory (@dirlist) {
729 next if $directory eq 'lib';
730 -d
"$htdocs/$directory/en" and push @themes, $directory;
737 if ( C4
::Context
->preference("marcflavour") eq "UNIMARC" ) {
742 tags
=> [ qw
/ 600ab 601ab 602a 604at 605a 606ax 610a / ],
748 tags
=> [ qw
/ 607a / ],
754 tags
=> [ qw
/ 500a 501a 503a / ],
760 tags
=> [ qw
/ 700ab 701ab 702ab / ],
761 sep
=> C4
::Context
->preference("UNIMARCAuthorsFacetsSeparator"),
766 tags
=> [ qw
/ 225a / ],
772 tags
=> [ qw
/ 995e / ],
776 unless ( C4
::Context
->preference("singleBranchMode")
777 || GetBranchesCount
() == 1 )
779 my $DisplayLibraryFacets = C4
::Context
->preference('DisplayLibraryFacets');
780 if ( $DisplayLibraryFacets eq 'both'
781 || $DisplayLibraryFacets eq 'holding' )
786 idx
=> 'holdingbranch',
787 label
=> 'HoldingLibrary',
788 tags
=> [qw
/ 995b /],
793 if ( $DisplayLibraryFacets eq 'both'
794 || $DisplayLibraryFacets eq 'home' )
800 label
=> 'HomeLibrary',
801 tags
=> [qw
/ 995a /],
812 tags
=> [ qw
/ 650a / ],
817 # label => 'People and Organizations',
818 # tags => [ qw/ 600a 610a 611a / ],
824 tags
=> [ qw
/ 651a / ],
830 tags
=> [ qw
/ 630a / ],
836 tags
=> [ qw
/ 100a 110a 700a / ],
842 tags
=> [ qw
/ 440a 490a / ],
847 label
=> 'ItemTypes',
848 tags
=> [ qw
/ 952y 942c / ],
854 tags
=> [ qw
/ 952c / ],
858 unless ( C4
::Context
->preference("singleBranchMode")
859 || GetBranchesCount
() == 1 )
861 my $DisplayLibraryFacets = C4
::Context
->preference('DisplayLibraryFacets');
862 if ( $DisplayLibraryFacets eq 'both'
863 || $DisplayLibraryFacets eq 'holding' )
868 idx
=> 'holdingbranch',
869 label
=> 'HoldingLibrary',
870 tags
=> [qw
/ 952b /],
875 if ( $DisplayLibraryFacets eq 'both'
876 || $DisplayLibraryFacets eq 'home' )
882 label
=> 'HomeLibrary',
883 tags
=> [qw
/ 952a /],
894 Return a href where a key is associated to a href. You give a query,
895 the name of the key among the fields returned by the query. If you
896 also give as third argument the name of the value, the function
897 returns a href of scalar. The optional 4th argument is an arrayref of
898 items passed to the C<execute()> call. It is designed to bind
899 parameters to any placeholders in your SQL.
908 # generic href of any information on the item, href of href.
909 my $iteminfos_of = get_infos_of($query, 'itemnumber');
910 print $iteminfos_of->{$itemnumber}{barcode};
912 # specific information, href of scalar
913 my $barcode_of_item = get_infos_of($query, 'itemnumber', 'barcode');
914 print $barcode_of_item->{$itemnumber};
919 my ( $query, $key_name, $value_name, $bind_params ) = @_;
921 my $dbh = C4
::Context
->dbh;
923 my $sth = $dbh->prepare($query);
924 $sth->execute( @
$bind_params );
927 while ( my $row = $sth->fetchrow_hashref ) {
928 if ( defined $value_name ) {
929 $infos_of{ $row->{$key_name} } = $row->{$value_name};
932 $infos_of{ $row->{$key_name} } = $row;
940 =head2 get_notforloan_label_of
942 my $notforloan_label_of = get_notforloan_label_of();
944 Each authorised value of notforloan (information available in items and
945 itemtypes) is link to a single label.
947 Returns a href where keys are authorised values and values are corresponding
950 foreach my $authorised_value (keys %{$notforloan_label_of}) {
952 "authorised_value: %s => %s\n",
954 $notforloan_label_of->{$authorised_value}
960 # FIXME - why not use GetAuthorisedValues ??
962 sub get_notforloan_label_of
{
963 my $dbh = C4
::Context
->dbh;
966 SELECT authorised_value
967 FROM marc_subfield_structure
968 WHERE kohafield = \'items.notforloan\'
971 my $sth = $dbh->prepare($query);
973 my ($statuscode) = $sth->fetchrow_array();
978 FROM authorised_values
981 $sth = $dbh->prepare($query);
982 $sth->execute($statuscode);
983 my %notforloan_label_of;
984 while ( my $row = $sth->fetchrow_hashref ) {
985 $notforloan_label_of{ $row->{authorised_value
} } = $row->{lib
};
989 return \
%notforloan_label_of;
992 =head2 displayServers
994 my $servers = displayServers();
995 my $servers = displayServers( $position );
996 my $servers = displayServers( $position, $type );
998 displayServers returns a listref of hashrefs, each containing
999 information about available z3950 servers. Each hashref has a format
1003 'checked' => 'checked',
1004 'encoding' => 'utf8',
1006 'id' => 'LIBRARY OF CONGRESS',
1010 'value' => 'lx2.loc.gov:210/',
1016 sub displayServers
{
1017 my ( $position, $type ) = @_;
1018 my $dbh = C4
::Context
->dbh;
1020 my $strsth = 'SELECT * FROM z3950servers';
1025 push @bind_params, $position;
1026 push @where_clauses, ' position = ? ';
1030 push @bind_params, $type;
1031 push @where_clauses, ' type = ? ';
1034 # reassemble where clause from where clause pieces
1035 if (@where_clauses) {
1036 $strsth .= ' WHERE ' . join( ' AND ', @where_clauses );
1039 my $rq = $dbh->prepare($strsth);
1040 $rq->execute(@bind_params);
1041 my @primaryserverloop;
1043 while ( my $data = $rq->fetchrow_hashref ) {
1044 push @primaryserverloop,
1045 { label
=> $data->{description
},
1046 id
=> $data->{name
},
1048 value
=> $data->{host
} . ":" . $data->{port
} . "/" . $data->{database
},
1049 encoding
=> ( $data->{encoding
} ?
$data->{encoding
} : "iso-5426" ),
1050 checked
=> "checked",
1051 icon
=> $data->{icon
},
1052 zed
=> $data->{type
} eq 'zed',
1053 opensearch
=> $data->{type
} eq 'opensearch'
1056 return \
@primaryserverloop;
1060 =head2 GetKohaImageurlFromAuthorisedValues
1062 $authhorised_value = GetKohaImageurlFromAuthorisedValues( $category, $authvalcode );
1064 Return the first url of the authorised value image represented by $lib.
1068 sub GetKohaImageurlFromAuthorisedValues
{
1069 my ( $category, $lib ) = @_;
1070 my $dbh = C4
::Context
->dbh;
1071 my $sth = $dbh->prepare("SELECT imageurl FROM authorised_values WHERE category=? AND lib =?");
1072 $sth->execute( $category, $lib );
1073 while ( my $data = $sth->fetchrow_hashref ) {
1074 return $data->{'imageurl'};
1078 =head2 GetAuthValCode
1080 $authvalcode = GetAuthValCode($kohafield,$frameworkcode);
1084 sub GetAuthValCode
{
1085 my ($kohafield,$fwcode) = @_;
1086 my $dbh = C4
::Context
->dbh;
1087 $fwcode='' unless $fwcode;
1088 my $sth = $dbh->prepare('select authorised_value from marc_subfield_structure where kohafield=? and frameworkcode=?');
1089 $sth->execute($kohafield,$fwcode);
1090 my ($authvalcode) = $sth->fetchrow_array;
1091 return $authvalcode;
1094 =head2 GetAuthValCodeFromField
1096 $authvalcode = GetAuthValCodeFromField($field,$subfield,$frameworkcode);
1098 C<$subfield> can be undefined
1102 sub GetAuthValCodeFromField
{
1103 my ($field,$subfield,$fwcode) = @_;
1104 my $dbh = C4
::Context
->dbh;
1105 $fwcode='' unless $fwcode;
1107 if (defined $subfield) {
1108 $sth = $dbh->prepare('select authorised_value from marc_subfield_structure where tagfield=? and tagsubfield=? and frameworkcode=?');
1109 $sth->execute($field,$subfield,$fwcode);
1111 $sth = $dbh->prepare('select authorised_value from marc_tag_structure where tagfield=? and frameworkcode=?');
1112 $sth->execute($field,$fwcode);
1114 my ($authvalcode) = $sth->fetchrow_array;
1115 return $authvalcode;
1118 =head2 GetAuthorisedValues
1120 $authvalues = GetAuthorisedValues([$category], [$selected]);
1122 This function returns all authorised values from the'authorised_value' table in a reference to array of hashrefs.
1124 C<$category> returns authorised values for just one category (optional).
1126 C<$selected> adds a "selected => 1" entry to the hash if the
1127 authorised_value matches it. B<NOTE:> this feature should be considered
1128 deprecated as it may be removed in the future.
1130 C<$opac> If set to a true value, displays OPAC descriptions rather than normal ones when they exist.
1134 sub GetAuthorisedValues
{
1135 my ( $category, $selected, $opac ) = @_;
1137 # TODO: the "selected" feature should be replaced by a utility function
1138 # somewhere else, it doesn't belong in here. For starters it makes
1139 # caching much more complicated. Or just let the UI logic handle it, it's
1142 # Is this cached already?
1143 $opac = $opac ?
1 : 0; # normalise to be safe
1145 C4
::Context
->userenv ? C4
::Context
->userenv->{"branch"} : "";
1146 my $selected_key = defined($selected) ?
$selected : '';
1148 "AuthorisedValues-$category-$selected_key-$opac-$branch_limit";
1149 my $cache = Koha
::Cache
->get_instance();
1150 my $result = $cache->get_from_cache($cache_key);
1151 return $result if $result;
1154 my $dbh = C4
::Context
->dbh;
1157 FROM authorised_values
1160 LEFT JOIN authorised_values_branches ON
( id
= av_id
)
1165 push @where_strings, "category = ?";
1166 push @where_args, $category;
1169 push @where_strings, "( branchcode = ? OR branchcode IS NULL )";
1170 push @where_args, $branch_limit;
1172 if(@where_strings > 0) {
1173 $query .= " WHERE " . join(" AND ", @where_strings);
1175 $query .= " GROUP BY lib";
1176 $query .= ' ORDER BY category, ' . (
1177 $opac ?
'COALESCE(lib_opac, lib)'
1181 my $sth = $dbh->prepare($query);
1183 $sth->execute( @where_args );
1184 while (my $data=$sth->fetchrow_hashref) {
1185 if ( defined $selected and $selected eq $data->{authorised_value
} ) {
1186 $data->{selected
} = 1;
1189 $data->{selected
} = 0;
1192 if ($opac && $data->{lib_opac
}) {
1193 $data->{lib
} = $data->{lib_opac
};
1195 push @results, $data;
1199 # We can't cache for long because of that "selected" thing which
1200 # makes it impossible to clear the cache without iterating through every
1201 # value, which sucks. This'll cover this request, and not a whole lot more.
1202 $cache->set_in_cache( $cache_key, \
@results, { deepcopy
=> 1, expiry
=> 5 } );
1206 =head2 GetAuthorisedValueCategories
1208 $auth_categories = GetAuthorisedValueCategories();
1210 Return an arrayref of all of the available authorised
1215 sub GetAuthorisedValueCategories
{
1216 my $dbh = C4
::Context
->dbh;
1217 my $sth = $dbh->prepare("SELECT DISTINCT category FROM authorised_values ORDER BY category");
1220 while (defined (my $category = $sth->fetchrow_array) ) {
1221 push @results, $category;
1226 =head2 IsAuthorisedValueCategory
1228 $is_auth_val_category = IsAuthorisedValueCategory($category);
1230 Returns whether a given category name is a valid one
1234 sub IsAuthorisedValueCategory
{
1235 my $category = shift;
1238 FROM authorised_values
1239 WHERE BINARY category=?
1242 my $sth = C4
::Context
->dbh->prepare($query);
1243 $sth->execute($category);
1244 $sth->fetchrow ?
return 1
1248 =head2 GetAuthorisedValueByCode
1250 $authorised_value = GetAuthorisedValueByCode( $category, $authvalcode, $opac );
1252 Return the lib attribute from authorised_values from the row identified
1253 by the passed category and code
1257 sub GetAuthorisedValueByCode
{
1258 my ( $category, $authvalcode, $opac ) = @_;
1260 my $field = $opac ?
'lib_opac' : 'lib';
1261 my $dbh = C4
::Context
->dbh;
1262 my $sth = $dbh->prepare("SELECT $field FROM authorised_values WHERE category=? AND authorised_value =?");
1263 $sth->execute( $category, $authvalcode );
1264 while ( my $data = $sth->fetchrow_hashref ) {
1265 return $data->{ $field };
1269 =head2 GetKohaAuthorisedValues
1271 Takes $kohafield, $fwcode as parameters.
1273 If $opac parameter is set to a true value, displays OPAC descriptions rather than normal ones when they exist.
1275 Returns hashref of Code => description
1277 Returns undef if no authorised value category is defined for the kohafield.
1281 sub GetKohaAuthorisedValues
{
1282 my ($kohafield,$fwcode,$opac) = @_;
1283 $fwcode='' unless $fwcode;
1285 my $dbh = C4
::Context
->dbh;
1286 my $avcode = GetAuthValCode
($kohafield,$fwcode);
1288 my $sth = $dbh->prepare("select authorised_value, lib, lib_opac from authorised_values where category=? ");
1289 $sth->execute($avcode);
1290 while ( my ($val, $lib, $lib_opac) = $sth->fetchrow_array ) {
1291 $values{$val} = ($opac && $lib_opac) ?
$lib_opac : $lib;
1299 =head2 GetKohaAuthorisedValuesFromField
1301 Takes $field, $subfield, $fwcode as parameters.
1303 If $opac parameter is set to a true value, displays OPAC descriptions rather than normal ones when they exist.
1304 $subfield can be undefined
1306 Returns hashref of Code => description
1308 Returns undef if no authorised value category is defined for the given field and subfield
1312 sub GetKohaAuthorisedValuesFromField
{
1313 my ($field, $subfield, $fwcode,$opac) = @_;
1314 $fwcode='' unless $fwcode;
1316 my $dbh = C4
::Context
->dbh;
1317 my $avcode = GetAuthValCodeFromField
($field, $subfield, $fwcode);
1319 my $sth = $dbh->prepare("select authorised_value, lib, lib_opac from authorised_values where category=? ");
1320 $sth->execute($avcode);
1321 while ( my ($val, $lib, $lib_opac) = $sth->fetchrow_array ) {
1322 $values{$val} = ($opac && $lib_opac) ?
$lib_opac : $lib;
1332 my $escaped_string = C4::Koha::xml_escape($string);
1334 Convert &, <, >, ', and " in a string to XML entities
1340 return '' unless defined $str;
1341 $str =~ s/&/&/g;
1344 $str =~ s/'/'/g;
1345 $str =~ s/"/"/g;
1349 =head2 GetKohaAuthorisedValueLib
1351 Takes $category, $authorised_value as parameters.
1353 If $opac parameter is set to a true value, displays OPAC descriptions rather than normal ones when they exist.
1355 Returns authorised value description
1359 sub GetKohaAuthorisedValueLib
{
1360 my ($category,$authorised_value,$opac) = @_;
1362 my $dbh = C4
::Context
->dbh;
1363 my $sth = $dbh->prepare("select lib, lib_opac from authorised_values where category=? and authorised_value=?");
1364 $sth->execute($category,$authorised_value);
1365 my $data = $sth->fetchrow_hashref;
1366 $value = ($opac && $$data{'lib_opac'}) ?
$$data{'lib_opac'} : $$data{'lib'};
1370 =head2 AddAuthorisedValue
1372 AddAuthorisedValue($category, $authorised_value, $lib, $lib_opac, $imageurl);
1374 Create a new authorised value.
1378 sub AddAuthorisedValue
{
1379 my ($category, $authorised_value, $lib, $lib_opac, $imageurl) = @_;
1381 my $dbh = C4
::Context
->dbh;
1383 INSERT INTO authorised_values
(category
, authorised_value
, lib
, lib_opac
, imageurl
)
1386 my $sth = $dbh->prepare($query);
1387 $sth->execute($category, $authorised_value, $lib, $lib_opac, $imageurl);
1390 =head2 display_marc_indicators
1392 my $display_form = C4::Koha::display_marc_indicators($field);
1394 C<$field> is a MARC::Field object
1396 Generate a display form of the indicators of a variable
1397 MARC field, replacing any blanks with '#'.
1401 sub display_marc_indicators
{
1403 my $indicators = '';
1404 if ($field->tag() >= 10) {
1405 $indicators = $field->indicator(1) . $field->indicator(2);
1406 $indicators =~ s/ /#/g;
1411 sub GetNormalizedUPC
{
1412 my ($record,$marcflavour) = @_;
1415 if ($marcflavour eq 'UNIMARC') {
1416 @fields = $record->field('072');
1417 foreach my $field (@fields) {
1418 my $upc = _normalize_match_point
($field->subfield('a'));
1425 else { # assume marc21 if not unimarc
1426 @fields = $record->field('024');
1427 foreach my $field (@fields) {
1428 my $indicator = $field->indicator(1);
1429 my $upc = _normalize_match_point
($field->subfield('a'));
1430 if ($indicator == 1 and $upc ne '') {
1437 # Normalizes and returns the first valid ISBN found in the record
1438 # ISBN13 are converted into ISBN10. This is required to get some book cover images.
1439 sub GetNormalizedISBN
{
1440 my ($isbn,$record,$marcflavour) = @_;
1443 # Koha attempts to store multiple ISBNs in biblioitems.isbn, separated by " | "
1444 # anything after " | " should be removed, along with the delimiter
1445 $isbn =~ s/(.*)( \| )(.*)/$1/;
1446 return _isbn_cleanup
($isbn);
1448 return unless $record;
1450 if ($marcflavour eq 'UNIMARC') {
1451 @fields = $record->field('010');
1452 foreach my $field (@fields) {
1453 my $isbn = $field->subfield('a');
1455 return _isbn_cleanup
($isbn);
1461 else { # assume marc21 if not unimarc
1462 @fields = $record->field('020');
1463 foreach my $field (@fields) {
1464 $isbn = $field->subfield('a');
1466 return _isbn_cleanup
($isbn);
1474 sub GetNormalizedEAN
{
1475 my ($record,$marcflavour) = @_;
1478 if ($marcflavour eq 'UNIMARC') {
1479 @fields = $record->field('073');
1480 foreach my $field (@fields) {
1481 $ean = _normalize_match_point
($field->subfield('a'));
1487 else { # assume marc21 if not unimarc
1488 @fields = $record->field('024');
1489 foreach my $field (@fields) {
1490 my $indicator = $field->indicator(1);
1491 $ean = _normalize_match_point
($field->subfield('a'));
1492 if ($indicator == 3 and $ean ne '') {
1498 sub GetNormalizedOCLCNumber
{
1499 my ($record,$marcflavour) = @_;
1502 if ($marcflavour eq 'UNIMARC') {
1503 # TODO: add UNIMARC fields
1505 else { # assume marc21 if not unimarc
1506 @fields = $record->field('035');
1507 foreach my $field (@fields) {
1508 $oclc = $field->subfield('a');
1509 if ($oclc =~ /OCoLC/) {
1510 $oclc =~ s/\(OCoLC\)//;
1519 sub GetAuthvalueDropbox
{
1520 my ( $authcat, $default ) = @_;
1521 my $branch_limit = C4
::Context
->userenv ? C4
::Context
->userenv->{"branch"} : "";
1522 my $dbh = C4
::Context
->dbh;
1526 FROM authorised_values
1529 LEFT JOIN authorised_values_branches ON
( id
= av_id
)
1534 $query .= " AND ( branchcode = ? OR branchcode IS NULL )" if $branch_limit;
1535 $query .= " GROUP BY lib ORDER BY category, lib, lib_opac";
1536 my $sth = $dbh->prepare($query);
1537 $sth->execute( $authcat, $branch_limit ?
$branch_limit : () );
1540 my $option_list = [];
1541 my @authorised_values = ( q{} );
1542 while (my $av = $sth->fetchrow_hashref) {
1543 push @
{$option_list}, {
1544 value
=> $av->{authorised_value
},
1545 label
=> $av->{lib
},
1546 default => ($default eq $av->{authorised_value
}),
1550 if ( @
{$option_list} ) {
1551 return $option_list;
1557 =head2 GetDailyQuote($opts)
1559 Takes a hashref of options
1561 Currently supported options are:
1563 'id' An exact quote id
1564 'random' Select a random quote
1565 noop When no option is passed in, this sub will return the quote timestamped for the current day
1567 The function returns an anonymous hash following this format:
1570 'source' => 'source-of-quote',
1571 'timestamp' => 'timestamp-value',
1572 'text' => 'text-of-quote',
1578 # This is definitely a candidate for some sort of caching once we finally settle caching/persistence issues...
1579 # at least for default option
1583 my $dbh = C4
::Context
->dbh;
1588 $query = 'SELECT * FROM quotes WHERE id = ?';
1589 $sth = $dbh->prepare($query);
1590 $sth->execute($opts{'id'});
1591 $quote = $sth->fetchrow_hashref();
1593 elsif ($opts{'random'}) {
1594 # Fall through... we also return a random quote as a catch-all if all else fails
1597 $query = 'SELECT * FROM quotes WHERE timestamp LIKE CONCAT(CURRENT_DATE,\'%\') ORDER BY timestamp DESC LIMIT 0,1';
1598 $sth = $dbh->prepare($query);
1600 $quote = $sth->fetchrow_hashref();
1602 unless ($quote) { # if there are not matches, choose a random quote
1603 # get a list of all available quote ids
1604 $sth = C4
::Context
->dbh->prepare('SELECT count(*) FROM quotes;');
1606 my $range = ($sth->fetchrow_array)[0];
1607 # chose a random id within that range if there is more than one quote
1608 my $offset = int(rand($range));
1610 $query = 'SELECT * FROM quotes ORDER BY id LIMIT 1 OFFSET ?';
1611 $sth = C4
::Context
->dbh->prepare($query);
1612 # see http://www.perlmonks.org/?node_id=837422 for why
1613 # we're being verbose and using bind_param
1614 $sth->bind_param(1, $offset, SQL_INTEGER
);
1616 $quote = $sth->fetchrow_hashref();
1617 # update the timestamp for that quote
1618 $query = 'UPDATE quotes SET timestamp = ? WHERE id = ?';
1619 $sth = C4
::Context
->dbh->prepare($query);
1621 DateTime
::Format
::MySQL
->format_datetime( dt_from_string
() ),
1628 sub _normalize_match_point
{
1629 my $match_point = shift;
1630 (my $normalized_match_point) = $match_point =~ /([\d-]*[X]*)/;
1631 $normalized_match_point =~ s/-//g;
1633 return $normalized_match_point;
1638 return NormalizeISBN
(
1641 format
=> 'ISBN-10',
1647 =head2 NormalizedISBN
1649 my $isbns = NormalizedISBN({
1651 strip_hyphens => [0,1],
1652 format => ['ISBN-10', 'ISBN-13']
1655 Returns an isbn validated by Business::ISBN.
1656 Optionally strips hyphens and/or forces the isbn
1657 to be of the specified format.
1659 If the string cannot be validated as an isbn,
1667 my $string = $params->{isbn
};
1668 my $strip_hyphens = $params->{strip_hyphens
};
1669 my $format = $params->{format
};
1671 return unless $string;
1673 my $isbn = Business
::ISBN
->new($string);
1675 if ( $isbn && $isbn->is_valid() ) {
1677 if ( $format eq 'ISBN-10' ) {
1678 $isbn = $isbn->as_isbn10();
1680 elsif ( $format eq 'ISBN-13' ) {
1681 $isbn = $isbn->as_isbn13();
1684 if ($strip_hyphens) {
1685 $string = $isbn->as_string( [] );
1687 $string = $isbn->as_string();
1694 =head2 GetVariationsOfISBN
1696 my @isbns = GetVariationsOfISBN( $isbn );
1698 Returns a list of varations of the given isbn in
1699 both ISBN-10 and ISBN-13 formats, with and without
1702 In a scalar context, the isbns are returned as a
1703 string delimited by ' | '.
1707 sub GetVariationsOfISBN
{
1710 return unless $isbn;
1714 push( @isbns, NormalizeISBN
({ isbn
=> $isbn }) );
1715 push( @isbns, NormalizeISBN
({ isbn
=> $isbn, format
=> 'ISBN-10' }) );
1716 push( @isbns, NormalizeISBN
({ isbn
=> $isbn, format
=> 'ISBN-13' }) );
1717 push( @isbns, NormalizeISBN
({ isbn
=> $isbn, format
=> 'ISBN-10', strip_hyphens
=> 1 }) );
1718 push( @isbns, NormalizeISBN
({ isbn
=> $isbn, format
=> 'ISBN-13', strip_hyphens
=> 1 }) );
1720 # Strip out any "empty" strings from the array
1721 @isbns = grep { defined($_) && $_ =~ /\S/ } @isbns;
1723 return wantarray ?
@isbns : join( " | ", @isbns );
1726 =head2 GetVariationsOfISBNs
1728 my @isbns = GetVariationsOfISBNs( @isbns );
1730 Returns a list of varations of the given isbns in
1731 both ISBN-10 and ISBN-13 formats, with and without
1734 In a scalar context, the isbns are returned as a
1735 string delimited by ' | '.
1739 sub GetVariationsOfISBNs
{
1742 @isbns = map { GetVariationsOfISBN
( $_ ) } @isbns;
1744 return wantarray ?
@isbns : join( " | ", @isbns );
1747 =head2 IsKohaFieldLinked
1749 my $is_linked = IsKohaFieldLinked({
1750 kohafield => $kohafield,
1751 frameworkcode => $frameworkcode,
1754 Return 1 if the field is linked
1758 sub IsKohaFieldLinked
{
1759 my ( $params ) = @_;
1760 my $kohafield = $params->{kohafield
};
1761 my $frameworkcode = $params->{frameworkcode
} || '';
1762 my $dbh = C4
::Context
->dbh;
1763 my $is_linked = $dbh->selectcol_arrayref( q
|
1765 FROM marc_subfield_structure
1766 WHERE frameworkcode
= ?
1768 |,{}, $frameworkcode, $kohafield );
1769 return $is_linked->[0];