3 # Copyright 2000-2002 Katipo Communications
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along with
17 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18 # Suite 330, Boston, MA 02111-1307 USA
25 use vars qw($VERSION @ISA @EXPORT $DEBUG);
34 &subfield_is_koha_internal_p
35 &GetPrinters &GetPrinter
36 &GetItemTypes &getitemtypeinfo
39 &getframeworks &getframeworkinfo
40 &getauthtypes &getauthtype
45 &getitemtypeimagesrcfromurl
47 &get_notforloan_label_of
51 &GetAuthorisedValueCategories
52 &GetKohaAuthorisedValues
54 &GetManagedTagSubfields
63 C4::Koha - Perl Module containing convenience functions for Koha scripts
72 Koha.pm provides many functions for Koha scripts.
81 $slash_date = &slashifyDate($dash_date);
83 Takes a string of the form "DD-MM-YYYY" (or anything separated by
84 dashes), converts it to the form "YYYY/MM/DD", and returns the result.
90 # accepts a date of the form xx-xx-xx[xx] and returns it in the
92 my @dateOut = split( '-', shift );
93 return ("$dateOut[2]/$dateOut[1]/$dateOut[0]");
99 my $string = DisplayISBN( $isbn );
105 if (length ($isbn)<13){
107 if ( substr( $isbn, 0, 1 ) <= 7 ) {
108 $seg1 = substr( $isbn, 0, 1 );
110 elsif ( substr( $isbn, 0, 2 ) <= 94 ) {
111 $seg1 = substr( $isbn, 0, 2 );
113 elsif ( substr( $isbn, 0, 3 ) <= 995 ) {
114 $seg1 = substr( $isbn, 0, 3 );
116 elsif ( substr( $isbn, 0, 4 ) <= 9989 ) {
117 $seg1 = substr( $isbn, 0, 4 );
120 $seg1 = substr( $isbn, 0, 5 );
122 my $x = substr( $isbn, length($seg1) );
124 if ( substr( $x, 0, 2 ) <= 19 ) {
126 # if(sTmp2 < 10) sTmp2 = "0" sTmp2;
127 $seg2 = substr( $x, 0, 2 );
129 elsif ( substr( $x, 0, 3 ) <= 699 ) {
130 $seg2 = substr( $x, 0, 3 );
132 elsif ( substr( $x, 0, 4 ) <= 8399 ) {
133 $seg2 = substr( $x, 0, 4 );
135 elsif ( substr( $x, 0, 5 ) <= 89999 ) {
136 $seg2 = substr( $x, 0, 5 );
138 elsif ( substr( $x, 0, 6 ) <= 9499999 ) {
139 $seg2 = substr( $x, 0, 6 );
142 $seg2 = substr( $x, 0, 7 );
144 my $seg3 = substr( $x, length($seg2) );
145 $seg3 = substr( $seg3, 0, length($seg3) - 1 );
146 my $seg4 = substr( $x, -1, 1 );
147 return "$seg1-$seg2-$seg3-$seg4";
150 $seg1 = substr( $isbn, 0, 3 );
152 if ( substr( $isbn, 3, 1 ) <= 7 ) {
153 $seg2 = substr( $isbn, 3, 1 );
155 elsif ( substr( $isbn, 3, 2 ) <= 94 ) {
156 $seg2 = substr( $isbn, 3, 2 );
158 elsif ( substr( $isbn, 3, 3 ) <= 995 ) {
159 $seg2 = substr( $isbn, 3, 3 );
161 elsif ( substr( $isbn, 3, 4 ) <= 9989 ) {
162 $seg2 = substr( $isbn, 3, 4 );
165 $seg2 = substr( $isbn, 3, 5 );
167 my $x = substr( $isbn, length($seg2) +3);
169 if ( substr( $x, 0, 2 ) <= 19 ) {
171 # if(sTmp2 < 10) sTmp2 = "0" sTmp2;
172 $seg3 = substr( $x, 0, 2 );
174 elsif ( substr( $x, 0, 3 ) <= 699 ) {
175 $seg3 = substr( $x, 0, 3 );
177 elsif ( substr( $x, 0, 4 ) <= 8399 ) {
178 $seg3 = substr( $x, 0, 4 );
180 elsif ( substr( $x, 0, 5 ) <= 89999 ) {
181 $seg3 = substr( $x, 0, 5 );
183 elsif ( substr( $x, 0, 6 ) <= 9499999 ) {
184 $seg3 = substr( $x, 0, 6 );
187 $seg3 = substr( $x, 0, 7 );
189 my $seg4 = substr( $x, length($seg3) );
190 $seg4 = substr( $seg4, 0, length($seg4) - 1 );
191 my $seg5 = substr( $x, -1, 1 );
192 return "$seg1-$seg2-$seg3-$seg4-$seg5";
196 # FIXME.. this should be moved to a MARC-specific module
197 sub subfield_is_koha_internal_p ($) {
200 # We could match on 'lib' and 'tab' (and 'mandatory', & more to come!)
201 # But real MARC subfields are always single-character
202 # so it really is safer just to check the length
204 return length $subfield != 1;
209 $itemtypes = &GetItemTypes();
211 Returns information about existing itemtypes.
213 build a HTML select with the following code :
215 =head3 in PERL SCRIPT
217 my $itemtypes = GetItemTypes;
219 foreach my $thisitemtype (sort keys %$itemtypes) {
220 my $selected = 1 if $thisitemtype eq $itemtype;
221 my %row =(value => $thisitemtype,
222 selected => $selected,
223 description => $itemtypes->{$thisitemtype}->{'description'},
225 push @itemtypesloop, \%row;
227 $template->param(itemtypeloop => \@itemtypesloop);
231 <form action='<!-- TMPL_VAR name="script_name" -->' method=post>
232 <select name="itemtype">
233 <option value="">Default</option>
234 <!-- TMPL_LOOP name="itemtypeloop" -->
235 <option value="<!-- TMPL_VAR name="value" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="description" --></option>
238 <input type=text name=searchfield value="<!-- TMPL_VAR name="searchfield" -->">
239 <input type="submit" value="OK" class="button">
246 # returns a reference to a hash of references to branches...
248 my $dbh = C4::Context->dbh;
253 my $sth = $dbh->prepare($query);
255 while ( my $IT = $sth->fetchrow_hashref ) {
256 $itemtypes{ $IT->{'itemtype'} } = $IT;
258 return ( \%itemtypes );
261 sub get_itemtypeinfos_of {
270 WHERE itemtype IN (' . join( ',', map( { "'" . $_ . "'" } @itemtypes ) ) . ')
273 return get_infos_of( $query, 'itemtype' );
276 # this is temporary until we separate collection codes and item types
280 my $dbh = C4::Context->dbh;
283 "SELECT * FROM authorised_values ORDER BY authorised_value");
285 while ( my $data = $sth->fetchrow_hashref ) {
286 if ( $data->{category} eq "CCODE" ) {
288 $results[$count] = $data;
294 return ( $count, @results );
299 $authtypes = &getauthtypes();
301 Returns information about existing authtypes.
303 build a HTML select with the following code :
305 =head3 in PERL SCRIPT
307 my $authtypes = getauthtypes;
309 foreach my $thisauthtype (keys %$authtypes) {
310 my $selected = 1 if $thisauthtype eq $authtype;
311 my %row =(value => $thisauthtype,
312 selected => $selected,
313 authtypetext => $authtypes->{$thisauthtype}->{'authtypetext'},
315 push @authtypesloop, \%row;
317 $template->param(itemtypeloop => \@itemtypesloop);
321 <form action='<!-- TMPL_VAR name="script_name" -->' method=post>
322 <select name="authtype">
323 <!-- TMPL_LOOP name="authtypeloop" -->
324 <option value="<!-- TMPL_VAR name="value" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="authtypetext" --></option>
327 <input type=text name=searchfield value="<!-- TMPL_VAR name="searchfield" -->">
328 <input type="submit" value="OK" class="button">
336 # returns a reference to a hash of references to authtypes...
338 my $dbh = C4::Context->dbh;
339 my $sth = $dbh->prepare("select * from auth_types order by authtypetext");
341 while ( my $IT = $sth->fetchrow_hashref ) {
342 $authtypes{ $IT->{'authtypecode'} } = $IT;
344 return ( \%authtypes );
348 my ($authtypecode) = @_;
350 # returns a reference to a hash of references to authtypes...
352 my $dbh = C4::Context->dbh;
353 my $sth = $dbh->prepare("select * from auth_types where authtypecode=?");
354 $sth->execute($authtypecode);
355 my $res = $sth->fetchrow_hashref;
361 $frameworks = &getframework();
363 Returns information about existing frameworks
365 build a HTML select with the following code :
367 =head3 in PERL SCRIPT
369 my $frameworks = frameworks();
371 foreach my $thisframework (keys %$frameworks) {
372 my $selected = 1 if $thisframework eq $frameworkcode;
373 my %row =(value => $thisframework,
374 selected => $selected,
375 description => $frameworks->{$thisframework}->{'frameworktext'},
377 push @frameworksloop, \%row;
379 $template->param(frameworkloop => \@frameworksloop);
383 <form action='<!-- TMPL_VAR name="script_name" -->' method=post>
384 <select name="frameworkcode">
385 <option value="">Default</option>
386 <!-- TMPL_LOOP name="frameworkloop" -->
387 <option value="<!-- TMPL_VAR name="value" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="frameworktext" --></option>
390 <input type=text name=searchfield value="<!-- TMPL_VAR name="searchfield" -->">
391 <input type="submit" value="OK" class="button">
399 # returns a reference to a hash of references to branches...
401 my $dbh = C4::Context->dbh;
402 my $sth = $dbh->prepare("select * from biblio_framework");
404 while ( my $IT = $sth->fetchrow_hashref ) {
405 $itemtypes{ $IT->{'frameworkcode'} } = $IT;
407 return ( \%itemtypes );
410 =head2 getframeworkinfo
412 $frameworkinfo = &getframeworkinfo($frameworkcode);
414 Returns information about an frameworkcode.
418 sub getframeworkinfo {
419 my ($frameworkcode) = @_;
420 my $dbh = C4::Context->dbh;
422 $dbh->prepare("select * from biblio_framework where frameworkcode=?");
423 $sth->execute($frameworkcode);
424 my $res = $sth->fetchrow_hashref;
428 =head2 getitemtypeinfo
430 $itemtype = &getitemtype($itemtype);
432 Returns information about an itemtype.
436 sub getitemtypeinfo {
438 my $dbh = C4::Context->dbh;
439 my $sth = $dbh->prepare("select * from itemtypes where itemtype=?");
440 $sth->execute($itemtype);
441 my $res = $sth->fetchrow_hashref;
443 $res->{imageurl} = getitemtypeimagesrcfromurl( $res->{imageurl} );
448 sub getitemtypeimagesrcfromurl {
451 if ( defined $imageurl and $imageurl !~ m/^http/ ) {
452 $imageurl = getitemtypeimagesrc() . '/' . $imageurl;
458 sub getitemtypeimagedir {
460 if ($src eq 'intranet') {
461 return C4::Context->config('intrahtdocs') . '/' .C4::Context->preference('template') . '/img/itemtypeimg';
464 return C4::Context->config('opachtdocs') . '/' . C4::Context->preference('template') . '/itemtypeimg';
468 sub getitemtypeimagesrc {
470 if ($src eq 'intranet') {
471 return '/intranet-tmpl' . '/' . C4::Context->preference('template') . '/img/itemtypeimg';
474 return '/opac-tmpl' . '/' . C4::Context->preference('template') . '/itemtypeimg';
478 =head3 _getImagesFromDirectory
480 Find all of the image files in a directory in the filesystem
485 returns: a list of images in that directory.
487 Notes: this does not traverse into subdirectories. See
488 _getSubdirectoryNames for help with that.
489 Images are assumed to be files with .gif or .png file extensions.
490 The image names returned do not have the directory name on them.
494 sub _getImagesFromDirectory {
495 my $directoryname = shift;
496 return unless defined $directoryname;
497 return unless -d $directoryname;
499 if ( opendir ( my $dh, $directoryname ) ) {
500 my @images = grep { /\.(gif|png)$/i } readdir( $dh );
504 warn "unable to opendir $directoryname: $!";
509 =head3 _getSubdirectoryNames
511 Find all of the directories in a directory in the filesystem
516 returns: a list of subdirectories in that directory.
518 Notes: this does not traverse into subdirectories. Only the first
519 level of subdirectories are returned.
520 The directory names returned don't have the parent directory name
525 sub _getSubdirectoryNames {
526 my $directoryname = shift;
527 return unless defined $directoryname;
528 return unless -d $directoryname;
530 if ( opendir ( my $dh, $directoryname ) ) {
531 my @directories = grep { -d File::Spec->catfile( $directoryname, $_ ) && ! ( /^\./ ) } readdir( $dh );
535 warn "unable to opendir $directoryname: $!";
542 returns: a listref of hashrefs. Each hash represents another collection of images.
543 { imagesetname => 'npl', # the name of the image set (npl is the original one)
544 images => listref of image hashrefs
547 each image is represented by a hashref like this:
548 { KohaImage => 'npl/image.gif',
549 StaffImageUrl => '/intranet-tmpl/prog/img/itemtypeimg/npl/image.gif',
550 OpacImageURL => '/opac-tmpl/prog/itemtypeimg/npl/image.gif'
551 checked => 0 or 1: was this the image passed to this method?
552 Note: I'd like to remove this somehow.
559 my $checked = $params{'checked'} || '';
561 my $paths = { staff => { filesystem => getitemtypeimagedir('intranet'),
562 url => getitemtypeimagesrc('intranet'),
564 opac => { filesystem => getitemtypeimagedir('opac'),
565 url => getitemtypeimagesrc('opac'),
569 my @imagesets = (); # list of hasrefs of image set data to pass to template
570 my @subdirectories = _getSubdirectoryNames( $paths->{'staff'}{'filesystem'} );
572 foreach my $imagesubdir ( @subdirectories ) {
573 my @imagelist = (); # hashrefs of image info
574 my @imagenames = _getImagesFromDirectory( File::Spec->catfile( $paths->{'staff'}{'filesystem'}, $imagesubdir ) );
575 foreach my $thisimage ( @imagenames ) {
577 { KohaImage => "$imagesubdir/$thisimage",
578 StaffImageUrl => join( '/', $paths->{'staff'}{'url'}, $imagesubdir, $thisimage ),
579 OpacImageUrl => join( '/', $paths->{'opac'}{'url'}, $imagesubdir, $thisimage ),
580 checked => "$imagesubdir/$thisimage" eq $checked ? 1 : 0,
584 push @imagesets, { imagesetname => $imagesubdir,
585 images => \@imagelist };
593 $printers = &GetPrinters();
594 @queues = keys %$printers;
596 Returns information about existing printer queues.
598 C<$printers> is a reference-to-hash whose keys are the print queues
599 defined in the printers table of the Koha database. The values are
600 references-to-hash, whose keys are the fields in the printers table.
606 my $dbh = C4::Context->dbh;
607 my $sth = $dbh->prepare("select * from printers");
609 while ( my $printer = $sth->fetchrow_hashref ) {
610 $printers{ $printer->{'printqueue'} } = $printer;
612 return ( \%printers );
617 $printer = GetPrinter( $query, $printers );
621 sub GetPrinter ($$) {
622 my ( $query, $printers ) = @_; # get printer for this query from printers
623 my $printer = $query->param('printer');
624 my %cookie = $query->cookie('userenv');
625 ($printer) || ( $printer = $cookie{'printer'} ) || ( $printer = '' );
626 ( $printers->{$printer} ) || ( $printer = ( keys %$printers )[0] );
632 Returns the number of pages to display in a pagination bar, given the number
633 of items and the number of items per page.
638 my ( $nb_items, $nb_items_per_page ) = @_;
640 return int( ( $nb_items - 1 ) / $nb_items_per_page ) + 1;
645 (@themes) = &getallthemes('opac');
646 (@themes) = &getallthemes('intranet');
648 Returns an array of all available themes.
656 if ( $type eq 'intranet' ) {
657 $htdocs = C4::Context->config('intrahtdocs');
660 $htdocs = C4::Context->config('opachtdocs');
662 opendir D, "$htdocs";
663 my @dirlist = readdir D;
664 foreach my $directory (@dirlist) {
665 -d "$htdocs/$directory/en" and push @themes, $directory;
672 if ( C4::Context->preference("marcflavour") eq "UNIMARC" ) {
675 link_value => 'su-to',
676 label_value => 'Topics',
678 [ '600', '601', '602', '603', '604', '605', '606', '610' ],
682 link_value => 'su-geo',
683 label_value => 'Places',
688 link_value => 'su-ut',
689 label_value => 'Titles',
690 tags => [ '500', '501', '502', '503', '504', ],
695 label_value => 'Authors',
696 tags => [ '700', '701', '702', ],
701 label_value => 'Series',
710 link_value => 'branch',
711 label_value => 'Libraries',
716 push @$facets, $library_facet unless C4::Context->preference("singleBranchMode");
721 link_value => 'su-to',
722 label_value => 'Topics',
728 # link_value => 'su-na',
729 # label_value => 'People and Organizations',
730 # tags => ['600', '610', '611'],
734 link_value => 'su-geo',
735 label_value => 'Places',
740 link_value => 'su-ut',
741 label_value => 'Titles',
747 label_value => 'Authors',
748 tags => [ '100', '110', '700', ],
753 label_value => 'Series',
754 tags => [ '440', '490', ],
760 link_value => 'branch',
761 label_value => 'Libraries',
766 push @$facets, $library_facet unless C4::Context->preference("singleBranchMode");
773 Return a href where a key is associated to a href. You give a query, the
774 name of the key among the fields returned by the query. If you also give as
775 third argument the name of the value, the function returns a href of scalar.
784 # generic href of any information on the item, href of href.
785 my $iteminfos_of = get_infos_of($query, 'itemnumber');
786 print $iteminfos_of->{$itemnumber}{barcode};
788 # specific information, href of scalar
789 my $barcode_of_item = get_infos_of($query, 'itemnumber', 'barcode');
790 print $barcode_of_item->{$itemnumber};
795 my ( $query, $key_name, $value_name ) = @_;
797 my $dbh = C4::Context->dbh;
799 my $sth = $dbh->prepare($query);
803 while ( my $row = $sth->fetchrow_hashref ) {
804 if ( defined $value_name ) {
805 $infos_of{ $row->{$key_name} } = $row->{$value_name};
808 $infos_of{ $row->{$key_name} } = $row;
816 =head2 get_notforloan_label_of
818 my $notforloan_label_of = get_notforloan_label_of();
820 Each authorised value of notforloan (information available in items and
821 itemtypes) is link to a single label.
823 Returns a href where keys are authorised values and values are corresponding
826 foreach my $authorised_value (keys %{$notforloan_label_of}) {
828 "authorised_value: %s => %s\n",
830 $notforloan_label_of->{$authorised_value}
836 # FIXME - why not use GetAuthorisedValues ??
838 sub get_notforloan_label_of {
839 my $dbh = C4::Context->dbh;
842 SELECT authorised_value
843 FROM marc_subfield_structure
844 WHERE kohafield = \'items.notforloan\'
847 my $sth = $dbh->prepare($query);
849 my ($statuscode) = $sth->fetchrow_array();
854 FROM authorised_values
857 $sth = $dbh->prepare($query);
858 $sth->execute($statuscode);
859 my %notforloan_label_of;
860 while ( my $row = $sth->fetchrow_hashref ) {
861 $notforloan_label_of{ $row->{authorised_value} } = $row->{lib};
865 return \%notforloan_label_of;
869 my ( $position, $type ) = @_;
870 my $dbh = C4::Context->dbh;
871 my $strsth = "SELECT * FROM z3950servers where 1";
872 $strsth .= " AND position=\"$position\"" if ($position);
873 $strsth .= " AND type=\"$type\"" if ($type);
874 my $rq = $dbh->prepare($strsth);
876 my @primaryserverloop;
878 while ( my $data = $rq->fetchrow_hashref ) {
880 $cell{label} = $data->{'description'};
881 $cell{id} = $data->{'name'};
884 . ( $data->{port} ? ":" . $data->{port} : "" ) . "/"
886 if ( $data->{host} );
887 $cell{checked} = $data->{checked};
888 push @primaryserverloop,
890 label => $data->{description},
893 value => $data->{host} . ":"
894 . $data->{port} . "/"
896 encoding => ($data->{encoding}?$data->{encoding}:"iso-5426"),
897 checked => "checked",
898 icon => $data->{icon},
899 zed => $data->{type} eq 'zed',
900 opensearch => $data->{type} eq 'opensearch'
903 return \@primaryserverloop;
906 sub displaySecondaryServers {
908 # my $secondary_servers_loop = [
909 # { inner_sup_servers_loop => [
910 # {label => "Google", id=>"GOOG", value=>"google",icon => "google.ico",opensearch => "1"},
911 # {label => "Yahoo", id=>"YAH", value=>"yahoo", icon =>"yahoo.ico", zed => "1"},
912 # {label => "Worldcat", id=>"WCT", value=>"worldcat", icon => "worldcat.gif", zed => "1"},
913 # {label => "Library of Congress", id=>"LOC", name=> "server", value=>"z3950.loc.gov:7090/Voyager", icon =>"loc.ico", zed => "1"},
917 return; #$secondary_servers_loop;
920 =head2 GetAuthValCode
922 $authvalcode = GetAuthValCode($kohafield,$frameworkcode);
927 my ($kohafield,$fwcode) = @_;
928 my $dbh = C4::Context->dbh;
929 $fwcode='' unless $fwcode;
930 my $sth = $dbh->prepare('select authorised_value from marc_subfield_structure where kohafield=? and frameworkcode=?');
931 $sth->execute($kohafield,$fwcode);
932 my ($authvalcode) = $sth->fetchrow_array;
936 =head2 GetAuthorisedValues
938 $authvalues = GetAuthorisedValues($category);
940 this function get all authorised values from 'authosied_value' table into a reference to array which
941 each value containt an hashref.
943 Set C<$category> on input args if you want to limits your query to this one. This params is not mandatory.
947 sub GetAuthorisedValues {
948 my ($category,$selected) = @_;
951 my $dbh = C4::Context->dbh;
952 my $query = "SELECT * FROM authorised_values";
953 $query .= " WHERE category = '" . $category . "'" if $category;
955 my $sth = $dbh->prepare($query);
957 while (my $data=$sth->fetchrow_hashref) {
958 if ($selected eq $data->{'authorised_value'} ) {
959 $data->{'selected'} = 1;
961 $results[$count] = $data;
964 #my $data = $sth->fetchall_arrayref({});
965 return \@results; #$data;
968 =head2 GetAuthorisedValueCategories
970 $auth_categories = GetAuthorisedValueCategories();
972 Return an arrayref of all of the available authorised
977 sub GetAuthorisedValueCategories {
978 my $dbh = C4::Context->dbh;
979 my $sth = $dbh->prepare("SELECT DISTINCT category FROM authorised_values ORDER BY category");
982 while (my $category = $sth->fetchrow_array) {
983 push @results, $category;
988 =head2 GetKohaAuthorisedValues
990 Takes $kohafield, $fwcode as parameters.
991 Returns hashref of Code => description
993 if no authorised value category is defined for the kohafield.
997 sub GetKohaAuthorisedValues {
998 my ($kohafield,$fwcode,$codedvalue) = @_;
999 $fwcode='' unless $fwcode;
1001 my $dbh = C4::Context->dbh;
1002 my $avcode = GetAuthValCode($kohafield,$fwcode);
1004 my $sth = $dbh->prepare("select authorised_value, lib from authorised_values where category=? ");
1005 $sth->execute($avcode);
1006 while ( my ($val, $lib) = $sth->fetchrow_array ) {
1007 $values{$val}= $lib;
1015 =head2 GetManagedTagSubfields
1019 $res = GetManagedTagSubfields();
1023 Returns a reference to a big hash of hash, with the Marc structure fro the given frameworkcode
1025 NOTE: This function is used only by the (incomplete) bulk editing feature. Since
1026 that feature currently does not deal with items and biblioitems changes
1027 correctly, those tags are specifically excluded from the list prepared
1030 For future reference, if a bulk item editing feature is implemented at some point, it
1031 needs some design thought -- for example, circulation status fields should not
1032 be changed willy-nilly.
1036 sub GetManagedTagSubfields{
1037 my $dbh=C4::Context->dbh;
1038 my $rq=$dbh->prepare(qq|
1040 DISTINCT CONCAT( marc_subfield_structure.tagfield, tagsubfield ) AS tagsubfield,
1041 marc_subfield_structure.liblibrarian as subfielddesc,
1042 marc_tag_structure.liblibrarian as tagdesc
1043 FROM marc_subfield_structure
1044 LEFT JOIN marc_tag_structure
1045 ON marc_tag_structure.tagfield = marc_subfield_structure.tagfield
1046 AND marc_tag_structure.frameworkcode = marc_subfield_structure.frameworkcode
1047 WHERE marc_subfield_structure.tab>=0
1048 AND marc_tag_structure.tagfield NOT IN (SELECT tagfield FROM marc_subfield_structure WHERE kohafield like 'items.%')
1049 AND marc_tag_structure.tagfield NOT IN (SELECT tagfield FROM marc_subfield_structure WHERE kohafield = 'biblioitems.itemtype')
1050 AND marc_subfield_structure.kohafield <> 'biblio.biblionumber'
1051 AND marc_subfield_structure.kohafield <> 'biblioitems.biblioitemnumber'
1052 ORDER BY marc_subfield_structure.tagfield, tagsubfield|);
1054 my $data=$rq->fetchall_arrayref({});
1058 =head2 display_marc_indicators
1062 # field is a MARC::Field object
1063 my $display_form = C4::Koha::display_marc_indicators($field);
1067 Generate a display form of the indicators of a variable
1068 MARC field, replacing any blanks with '#'.
1072 sub display_marc_indicators {
1074 my $indicators = '';
1075 if ($field->tag() >= 10) {
1076 $indicators = $field->indicator(1) . $field->indicator(2);
1077 $indicators =~ s/ /#/g;