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 # FIXME - C4::Search uses C4::Reserves2, which uses C4::Search.
26 # So Perl complains that all of the functions here get redefined.
29 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
31 # set the version for version checking
36 C4::Search - Functions for searching the Koha catalog and other databases
42 my ($count, @results) = catalogsearch($env, $type, $search, $num, $offset);
46 This module provides the searching facilities for the Koha catalog and
49 C<&catalogsearch> is a front end to all the other searches. Depending
50 on what is passed to it, it calls the appropriate search function.
61 &CatSearch &BornameSearch &ItemInfo &KeywordSearch &subsearch
62 &itemdata &bibdata &GetItems &borrdata &itemnodata &itemcount
63 &borrdata2 &NewBorrowerNumber &bibitemdata &borrissues
64 &getboracctrecord &ItemType &itemissues &subject &subtitle
65 &addauthor &bibitems &barcodes &findguarantees &allissues
66 &findguarantor &getwebsites &getwebbiblioitems &catalogsearch &itemcount2
67 &isbnsearch &breedingsearch &getallthemes &getalllanguages &getbranchname &getborrowercategory);
68 # make all your functions, whether exported or not;
72 my (@results) = newsearch($itemtype,$duration,$number_of_results,$startfrom);
73 c<newsearch> find biblio acquired recently (last 30 days)
76 my ($itemtype,$duration,$num,$offset)=@_;
78 my $dbh = C4::Context->dbh;
79 my $sth=$dbh->prepare("SELECT to_days( now( ) ) - to_days( dateaccessioned ) AS duration, biblio.biblionumber, barcode, title, author, classification, itemtype, dewey, dateaccessioned, price, replacementprice
80 FROM items, biblio, biblioitems
81 WHERE biblio.biblionumber = biblioitems.biblionumber AND
82 items.biblionumber = biblio.biblionumber AND
83 to_days( now( ) ) - to_days( dateaccessioned ) < ? and itemtype=?
84 ORDER BY duration ASC ");
85 $sth->execute($duration,$itemtype);
88 while (my $line = $sth->fetchrow_hashref) {
89 if ($i>=$offset && $i+$offset<$num) {
100 ($num_children, $children_arrayref) = &findguarantees($parent_borrno);
101 $child0_cardno = $children_arrayref->[0]{"cardnumber"};
102 $child0_borrno = $children_arrayref->[0]{"borrowernumber"};
104 C<&findguarantees> takes a borrower number (e.g., that of a patron
105 with children) and looks up the borrowers who are guaranteed by that
106 borrower (i.e., the patron's children).
108 C<&findguarantees> returns two values: an integer giving the number of
109 borrowers guaranteed by C<$parent_borrno>, and a reference to an array
110 of references to hash, which gives the actual results.
116 my $dbh = C4::Context->dbh;
117 my $query="select cardnumber,borrowernumber, firstname, surname from borrowers where
118 guarantor='$bornum'";
119 my $sth=$dbh->prepare($query);
123 while (my $data = $sth->fetchrow_hashref)
128 return (scalar(@dat), \@dat);
133 $guarantor = &findguarantor($borrower_no);
134 $guarantor_cardno = $guarantor->{"cardnumber"};
135 $guarantor_surname = $guarantor->{"surname"};
138 C<&findguarantor> takes a borrower number (presumably that of a child
139 patron), finds the guarantor for C<$borrower_no> (the child's parent),
140 and returns the record for the guarantor.
142 C<&findguarantor> returns a reference-to-hash. Its keys are the fields
143 from the C<borrowers> database table;
149 my $dbh = C4::Context->dbh;
150 my $query="select guarantor from borrowers where
151 borrowernumber='$bornum'";
152 my $sth=$dbh->prepare($query);
154 my $data=$sth->fetchrow_hashref;
156 $query="Select * from borrowers where
157 borrowernumber='$data->{'guarantor'}'";
158 $sth=$dbh->prepare($query);
160 $data=$sth->fetchrow_hashref;
165 =item NewBorrowerNumber
167 $num = &NewBorrowerNumber();
169 Allocates a new, unused borrower number, and returns it.
173 # FIXME - This is identical to C4::Circulation::Borrower::NewBorrowerNumber.
174 # Pick one and stick with it. Preferably use the other one. This function
175 # doesn't belong in C4::Search.
176 sub NewBorrowerNumber {
177 my $dbh = C4::Context->dbh;
178 my $sth=$dbh->prepare("Select max(borrowernumber) from borrowers");
180 my $data=$sth->fetchrow_hashref;
182 $data->{'max(borrowernumber)'}++;
183 return($data->{'max(borrowernumber)'});
188 ($count, @results) = &catalogsearch($env, $type, $search, $num, $offset);
190 This is primarily a front-end to other, more specialized catalog
191 search functions: if C<$search-E<gt>{itemnumber}> or
192 C<$search-E<gt>{isbn}> is given, C<&catalogsearch> uses a precise
193 C<&CatSearch>. If $search->{subject} is given, it runs a subject
194 C<&CatSearch>. If C<$search-E<gt>{keyword}> is given, it runs a
195 C<&KeywordSearch>. Otherwise, it runs a loose C<&CatSearch>.
197 If C<$env-E<gt>{itemcount}> is 1, then C<&catalogsearch> also counts
198 the items for each result, and adds several keys:
204 The total number of copies of this book.
206 =item C<locationhash>
208 This is a reference-to-hash; the keys are the names of branches where
209 this book may be found, and the values are the number of copies at
214 A descriptive string saying where the book is located, and how many
215 copies there are, if greater than 1.
219 The book's subject, with spaces replaced with C<%20>, presumably for
227 my ($env,$type,$search,$num,$offset)=@_;
228 my $dbh = C4::Context->dbh;
229 # foreach my $key (%$search){
230 # $search->{$key}=$dbh->quote($search->{$key});
232 my ($count,@results);
233 # print STDERR "Doing a search \n";
234 if ($search->{'itemnumber'} ne '' || $search->{'isbn'} ne ''){
235 print STDERR "Doing a precise search\n";
236 ($count,@results)=CatSearch($env,'precise',$search,$num,$offset);
237 } elsif ($search->{'subject'} ne ''){
238 ($count,@results)=CatSearch($env,'subject',$search,$num,$offset);
239 } elsif ($search->{'keyword'} ne ''){
240 ($count,@results)=&KeywordSearch($env,'keyword',$search,$num,$offset);
242 ($count,@results)=CatSearch($env,'loose',$search,$num,$offset);
245 if ($env->{itemcount} eq '1') {
246 foreach my $data (@results){
247 my ($counts) = itemcount2($env, $data->{'biblionumber'}, 'intra');
248 my $subject2=$data->{'subject'};
249 $subject2=~ s/ /%20/g;
250 $data->{'itemcount'}=$counts->{'total'};
251 my $totalitemcounts=0;
252 foreach my $key (keys %$counts){
253 if ($key ne 'total'){ # FIXME - Should ignore 'order', too.
254 #$data->{'location'}.="$key $counts->{$key} ";
255 $totalitemcounts+=$counts->{$key};
256 $data->{'locationhash'}->{$key}=$counts->{$key};
260 my $notavailabletext='';
261 foreach (sort keys %{$data->{'locationhash'}}) {
262 if ($_ eq 'notavailable') {
263 $notavailabletext="Not available";
264 my $c=$data->{'locationhash'}->{$_};
265 if ($totalitemcounts>1) {
266 $notavailabletext.=" ($c)";
270 my $c=$data->{'locationhash'}->{$_};
271 if ($totalitemcounts>1) {
272 $locationtext.=" ($c), ";
276 if ($notavailabletext) {
277 $locationtext.=$notavailabletext;
279 $locationtext=~s/, $//;
281 $data->{'location'}=$locationtext;
282 $data->{'subject2'}=$subject2;
285 return ($count,@results);
290 $search = { "keyword" => "One or more keywords",
291 "class" => "VID|CD", # Limit search to fiction and CDs
294 ($count, @results) = &KeywordSearch($env, $type, $search, $num, $offset);
296 C<&KeywordSearch> searches the catalog by keyword: given a string
297 (C<$search-E<gt>{"keyword"}> consisting of a space-separated list of
298 keywords, it looks for books that contain any of those keywords in any
299 of a number of places.
301 C<&KeywordSearch> looks for keywords in the book title (and subtitle),
302 series name, notes (both C<biblio.notes> and C<biblioitems.notes>),
305 C<$search-E<gt>{"class"}> can be set to a C<|> (pipe)-separated list of
306 item class codes (e.g., "F" for fiction, "JNF" for junior nonfiction,
307 etc.). In this case, the search will be restricted to just those
310 If C<$search-E<gt>{"class"}> is not specified, you may specify
311 C<$search-E<gt>{"dewey"}>. This will restrict the search to that
312 particular Dewey Decimal Classification category. Setting
313 C<$search-E<gt>{"dewey"}> to "513" will return books about arithmetic,
314 whereas setting it to "5" will return all books with Dewey code 5I<xx>
315 (Science and Mathematics).
317 C<$env> and C<$type> are ignored.
319 C<$offset> and C<$num> specify the subset of results to return.
320 C<$num> specifies the number of results to return, and C<$offset> is
321 the number of the first result. Thus, setting C<$offset> to 100 and
322 C<$num> to 5 will return results 100 through 104 inclusive.
327 my ($env,$type,$search,$num,$offset)=@_;
328 my $dbh = C4::Context->dbh;
329 $search->{'keyword'}=~ s/ +$//;
330 $search->{'keyword'}=~ s/'/\\'/;
331 my @key=split(' ',$search->{'keyword'});
332 # FIXME - Naive users might enter comma-separated
333 # words, e.g., "training, animal". Ought to cope with
337 my %biblionumbers; # Set of biblionumbers returned by the
340 # FIXME - Ought to filter the stopwords out of the list of keywords.
341 # @key = map { !defined($stopwords{$_}) } @key;
343 # FIXME - The way this code is currently set up, it looks for all of
344 # the keywords first in (title, notes, seriestitle), then in the
345 # subtitle, then in the subject. Thus, if you look for keywords
346 # "science fiction", this search won't find a book with
347 # title = "How to write fiction"
348 # subtitle = "A science-based approach"
349 # Is this the desired effect? If not, then the first SQL query
350 # should look in the biblio, subtitle, and subject tables all at
351 # once. The way the first query is built can accomodate this easily.
353 # Look for keywords in table 'biblio'.
355 # Build an SQL query that finds each of the keywords in any of the
356 # title, biblio.notes, or seriestitle. To do this, we'll build up an
357 # array of clauses, one for each keyword.
358 my $query; # The SQL query
359 my @clauses = (); # The search clauses
361 $query = <<EOT; # Beginning of the query
366 foreach my $keyword (@key)
368 my @subclauses = (); # Subclauses, one for each field we're
371 # For each field we're searching on, create a subclause that'll
372 # match the current keyword in the current field.
373 foreach my $field (qw(title notes seriestitle author))
376 "$field LIKE '\Q$keyword\E%' OR $field LIKE '% \Q$keyword\E%'";
378 # (Yes, this could have been done as
379 # @subclauses = map {...} qw(field1 field2 ...)
380 # )but I think this way is more readable.
382 # Construct the current clause by joining the subclauses.
383 push @clauses, "(" . join(")\n\tOR (", @subclauses) . ")";
385 # Now join all of the clauses together and append to the query.
386 $query .= "(" . join(")\nAND (", @clauses) . ")";
388 # FIXME - Perhaps use $sth->bind_columns() ? Documented as the most
389 # efficient way to fetch data.
390 my $sth=$dbh->prepare($query);
392 while (my @res = $sth->fetchrow_array) {
395 $biblionumbers{$_} = 1; # Add these results to the set
400 # Now look for keywords in the 'bibliosubtitle' table.
402 # Again, we build a list of clauses from the keywords.
404 $query = "SELECT biblionumber FROM bibliosubtitle WHERE ";
405 foreach my $keyword (@key)
408 "subtitle LIKE '\Q$keyword\E%' OR subtitle like '% \Q$keyword\E%'";
410 $query .= "(" . join(") AND (", @clauses) . ")";
412 $sth=$dbh->prepare($query);
414 while (my @res = $sth->fetchrow_array) {
417 $biblionumbers{$_} = 1; # Add these results to the set
422 # Look for the keywords in the notes for individual items
423 # ('biblioitems.notes')
425 # Again, we build a list of clauses from the keywords.
427 $query = "SELECT biblionumber FROM biblioitems WHERE ";
428 foreach my $keyword (@key)
431 "notes LIKE '\Q$keyword\E%' OR notes like '% \Q$keyword\E%'";
433 $query .= "(" . join(") AND (", @clauses) . ")";
435 $sth=$dbh->prepare($query);
437 while (my @res = $sth->fetchrow_array) {
440 $biblionumbers{$_} = 1; # Add these results to the set
445 # Look for keywords in the 'bibliosubject' table.
447 # FIXME - The other queries look for words in the desired field that
448 # begin with the individual keywords the user entered. This one
449 # searches for the literal string the user entered. Is this the
451 # Note in particular that spaces are retained: if the user typed
453 # (with two spaces), this won't find the subject "science fiction"
454 # (one space). Likewise, a search for "%" will return absolutely
456 # If this isn't the desired effect, see the previous searches for
459 $sth=$dbh->prepare("Select biblionumber from bibliosubject where subject
460 like '%$search->{'keyword'}%' group by biblionumber");
463 while (my @res = $sth->fetchrow_array) {
466 $biblionumbers{$_} = 1; # Add these results to the set
476 my @res = keys %biblionumbers;
480 # print "count $count";
481 if ($search->{'class'} ne ''){
483 my $query="select * from biblio,biblioitems where
484 biblio.biblionumber='$res[$i2]' and
485 biblio.biblionumber=biblioitems.biblionumber ";
486 if ($search->{'class'} ne ''){ # FIXME - Redundant
487 my @temp=split(/\|/,$search->{'class'});
489 $query.= "and ( itemtype='$temp[0]'";
490 for (my $i=1;$i<$count;$i++){
491 $query.=" or itemtype='$temp[$i]'";
495 my $sth=$dbh->prepare($query);
498 if (my $data2=$sth->fetchrow_hashref){
499 my $dewey= $data2->{'dewey'};
500 my $subclass=$data2->{'subclass'};
501 # FIXME - This next bit is bogus, because it assumes that the
502 # Dewey code is a floating-point number. It isn't. It's
503 # actually a string that mainly consists of numbers. In
504 # particular, "4" is not a valid Dewey code, although "004"
505 # is ("Data processing; Computer science"). Likewise, zeros
506 # after the decimal are significant ("575" is not the same as
507 # "575.0"; the latter is more specific). And "000" is a
508 # perfectly good Dewey code ("General works; computer
509 # science") and should not be interpreted to mean "this
510 # database entry does not have a Dewey code". That's what
513 ($dewey == 0) && ($dewey='');
514 ($dewey) && ($dewey.=" $subclass") ;
516 my $end=$offset +$num;
521 if ($i4 <=$end && $i4 > $offset){
522 $data2->{'dewey'}=$dewey;
525 # $res2[$i3]="$data2->{'author'}\t$data2->{'title'}\t$data2->{'biblionumber'}\t$data2->{'copyrightdate'}\t$dewey";
528 # print "in here $i3<br>";
539 # $search->{'class'} was not specified
541 # FIXME - This is bogus: it makes a separate query for each
542 # biblioitem, and returns results in apparently random order. It'd
543 # be much better to combine all of the previous queries into one big
544 # one (building it up a little at a time, of course), and have that
545 # big query select all of the desired fields, instead of just
548 while ($i2 < $num && $i2 < $count){
549 my $query="select * from biblio,biblioitems where
550 biblio.biblionumber='$res[$i2+$offset]' and
551 biblio.biblionumber=biblioitems.biblionumber ";
553 if ($search->{'dewey'} ne ''){
554 $query.= "and (dewey like '$search->{'dewey'}%') ";
557 my $sth=$dbh->prepare($query);
560 if (my $data2=$sth->fetchrow_hashref){
561 my $dewey= $data2->{'dewey'};
562 my $subclass=$data2->{'subclass'};
564 ($dewey == 0) && ($dewey='');
565 ($dewey) && ($dewey.=" $subclass") ;
567 $data2->{'dewey'}=$dewey;
570 # $res2[$i]="$data2->{'author'}\t$data2->{'title'}\t$data2->{'biblionumber'}\t$data2->{'copyrightdate'}\t$dewey";
579 return($count,@res2);
583 my ($env,$type,$search,$num,$offset)=@_;
584 my $dbh = C4::Context->dbh;
585 $search->{'keyword'}=~ s/ +$//;
586 $search->{'keyword'}=~ s/'/\\'/;
587 my @key=split(' ',$search->{'keyword'});
591 my $query ="Select * from biblio,bibliosubtitle,biblioitems where
592 biblio.biblionumber=biblioitems.biblionumber and
593 biblio.biblionumber=bibliosubtitle.biblionumber and
594 (((title like '$key[0]%' or title like '% $key[0]%')";
596 $query .= " and (title like '$key[$i]%' or title like '% $key[$i]%')";
599 $query.= ") or ((subtitle like '$key[0]%' or subtitle like '% $key[0]%')";
600 for ($i=1;$i<$count;$i++){
601 $query.= " and (subtitle like '$key[$i]%' or subtitle like '% $key[$i]%')";
603 $query.= ") or ((seriestitle like '$key[0]%' or seriestitle like '% $key[0]%')";
604 for ($i=1;$i<$count;$i++){
605 $query.=" and (seriestitle like '$key[$i]%' or seriestitle like '% $key[$i]%')";
607 $query.= ") or ((biblio.notes like '$key[0]%' or biblio.notes like '% $key[0]%')";
608 for ($i=1;$i<$count;$i++){
609 $query.=" and (biblio.notes like '$key[$i]%' or biblio.notes like '% $key[$i]%')";
611 $query.= ") or ((biblioitems.notes like '$key[0]%' or biblioitems.notes like '% $key[0]%')";
612 for ($i=1;$i<$count;$i++){
613 $query.=" and (biblioitems.notes like '$key[$i]%' or biblioitems.notes like '% $key[$i]%')";
615 if ($search->{'keyword'} =~ /new zealand/i){
616 $query.= "or (title like 'nz%' or title like '% nz %' or title like '% nz' or subtitle like 'nz%'
617 or subtitle like '% nz %' or subtitle like '% nz' or author like 'nz %'
618 or author like '% nz %' or author like '% nz')"
620 if ($search->{'keyword'} eq 'nz' || $search->{'keyword'} eq 'NZ' ||
621 $search->{'keyword'} =~ /nz /i || $search->{'keyword'} =~ / nz /i ||
622 $search->{'keyword'} =~ / nz/i){
623 $query.= "or (title like 'new zealand%' or title like '% new zealand %'
624 or title like '% new zealand' or subtitle like 'new zealand%' or
625 subtitle like '% new zealand %'
626 or subtitle like '% new zealand' or author like 'new zealand%'
627 or author like '% new zealand %' or author like '% new zealand' or
628 seriestitle like 'new zealand%' or seriestitle like '% new zealand %'
629 or seriestitle like '% new zealand')"
632 if ($search->{'class'} ne ''){
633 my @temp=split(/\|/,$search->{'class'});
635 $query.= "and ( itemtype='$temp[0]'";
636 for (my $i=1;$i<$count;$i++){
637 $query.=" or itemtype='$temp[$i]'";
641 if ($search->{'dewey'} ne ''){
642 $query.= "and (dewey like '$search->{'dewey'}%') ";
644 $query.="group by biblio.biblionumber";
645 #$query.=" order by author,title";
647 my $sth=$dbh->prepare($query);
650 while (my $data=$sth->fetchrow_hashref){
651 # my $sti=$dbh->prepare("select dewey,subclass from biblioitems where biblionumber=$data->{'biblionumber'}
654 # my ($dewey, $subclass) = $sti->fetchrow;
655 my $dewey=$data->{'dewey'};
656 my $subclass=$data->{'subclass'};
658 ($dewey == 0) && ($dewey='');
659 ($dewey) && ($dewey.=" $subclass");
661 $results[$i]="$data->{'author'}\t$data->{'title'}\t$data->{'biblionumber'}\t$data->{'copyrightdate'}\t$dewey";
662 # print $results[$i];
666 $sth=$dbh->prepare("Select biblionumber from bibliosubject where subject
667 like '%$search->{'keyword'}%' group by biblionumber");
669 while (my $data=$sth->fetchrow_hashref){
670 $query="Select * from biblio,biblioitems where
671 biblio.biblionumber=$data->{'biblionumber'} and
672 biblio.biblionumber=biblioitems.biblionumber ";
673 if ($search->{'class'} ne ''){
674 my @temp=split(/\|/,$search->{'class'});
676 $query.= " and ( itemtype='$temp[0]'";
677 for (my $i=1;$i<$count;$i++){
678 $query.=" or itemtype='$temp[$i]'";
683 if ($search->{'dewey'} ne ''){
684 $query.= "and (dewey like '$search->{'dewey'}%') ";
686 my $sth2=$dbh->prepare($query);
689 while (my $data2=$sth2->fetchrow_hashref){
690 my $dewey= $data2->{'dewey'};
691 my $subclass=$data2->{'subclass'};
693 ($dewey == 0) && ($dewey='');
694 ($dewey) && ($dewey.=" $subclass") ;
696 $results[$i]="$data2->{'author'}\t$data2->{'title'}\t$data2->{'biblionumber'}\t$data2->{'copyrightdate'}\t$dewey";
697 # print $results[$i];
703 @results=sort @results;
710 while ($i2 < $count){
711 if ($results[$i2] ne $res[$i-1]){
712 $res[$i]=$results[$i2];
720 while ($i2 < $num && $i2 < $count){
721 $res2[$i2]=$res[$i2+$offset];
733 ($count, @results) = &CatSearch($env, $type, $search, $num, $offset);
735 C<&CatSearch> searches the Koha catalog. It returns a list whose first
736 element is the number of returned results, and whose subsequent
737 elements are the results themselves.
739 Each returned element is a reference-to-hash. Most of the keys are
740 simply the fields from the C<biblio> table in the Koha database, but
741 the following keys may also be present:
747 The book's illustrator.
757 C<$type> may be C<subject>, C<loose>, or C<precise>. This controls the
758 high-level behavior of C<&CatSearch>, as described below.
760 In many cases, the description below says that a certain field in the
761 database must match the search string. In these cases, it means that
762 the beginning of some word in the field must match the search string.
763 Thus, an author search for "sm" will return books whose author is
764 "John Smith" or "Mike Smalls", but not "Paul Grossman", since the "sm"
765 does not occur at the beginning of a word.
767 Note that within each search mode, the criteria are and-ed together.
768 That is, if you perform a loose search on the author "Jerome" and the
769 title "Boat", the search will only return books by Jerome containing
772 It is not possible to cross modes, e.g., set the author to "Asimov"
773 and the subject to "Math" in hopes of finding books on math by Asimov.
777 If C<$type> is set to C<loose>, the following search criteria may be
782 =item C<$search-E<gt>{author}>
784 The search string is a space-separated list of words. Each word must
785 match either the C<author> or C<additionalauthors> field.
787 =item C<$search-E<gt>{title}>
789 Each word in the search string must match the book title. If no author
790 is specified, the book subtitle will also be searched.
792 =item C<$search-E<gt>{abstract}>
794 Searches for the given search string in the book's abstract.
796 =item C<$search-E<gt>{'date-before'}>
798 Searches for books whose copyright date matches the search string.
799 That is, setting C<$search-E<gt>{'date-before'}> to "1985" will find
800 books written in 1985, and setting it to "198" will find books written
801 between 1980 and 1989.
803 =item C<$search-E<gt>{title}>
805 Searches by title are also affected by the value of
806 C<$search-E<gt>{"ttype"}>; if it is set to C<exact>, then the book
807 title, (one of) the series titleZ<>(s), or (one of) the unititleZ<>(s) must
808 match the search string exactly (the subtitle is not searched).
810 If C<$search-E<gt>{"ttype"}> is set to anything other than C<exact>,
811 each word in the search string must match the title, subtitle,
812 unititle, or series title.
814 =item C<$search-E<gt>{class}>
816 Restricts the search to certain item classes. The value of
817 C<$search-E<gt>{"class"}> is a | (pipe)-separated list of item types.
818 Thus, setting it to "F" restricts the search to fiction, and setting
819 it to "CD|CAS" will only look in compact disks and cassettes.
821 =item C<$search-E<gt>{dewey}>
823 Searches for books whose Dewey Decimal Classification code matches the
824 search string. That is, setting C<$search-E<gt>{"dewey"}> to "5" will
825 search for all books in 5I<xx> (Science and mathematics), setting it
826 to "54" will search for all books in 54I<x> (Chemistry), and setting
827 it to "546" will search for books on inorganic chemistry.
829 =item C<$search-E<gt>{publisher}>
831 Searches for books whose publisher contains the search string (unlike
832 other search criteria, C<$search-E<gt>{publisher}> is a string, not a
837 =head2 Subject search
839 If C<$type> is set to C<subject>, the following search criterion may
844 =item C<$search-E<gt>{subject}>
846 The search string is a space-separated list of words, each of which
847 must match the book's subject.
849 Special case: if C<$search-E<gt>{subject}> is set to C<nz>,
850 C<&CatSearch> will search for books whose subject is "New Zealand".
851 However, setting C<$search-E<gt>{subject}> to C<"nz football"> will
852 search for books on "nz" and "football", not books on "New Zealand"
857 =head2 Precise search
859 If C<$type> is set to C<precise>, the following search criteria may be
864 =item C<$search-E<gt>{item}>
866 Searches for books whose barcode exactly matches the search string.
868 =item C<$search-E<gt>{isbn}>
870 Searches for books whose ISBN exactly matches the search string.
874 For a loose search, if an author was specified, the results are
875 ordered by author and title. If no author was specified, the results
876 are ordered by title.
878 For other (non-loose) searches, if a subject was specified, the
879 results are ordered alphabetically by subject.
881 In all other cases (e.g., loose search by keyword), the results are
887 my ($env,$type,$search,$num,$offset)=@_;
888 my $dbh = C4::Context->dbh;
892 # Why not just use quotemeta to escape all questionable characters,
893 # not just single-quotes? Because that would also escape spaces,
894 # which would cause titles/authors/illustrators with a space to
895 # become unsearchable (Bug 197)
897 for my $field ('title', 'author', 'illustrator') {
898 $search->{$field} =~ s/['"]/\\\1/g;
901 my $title = lc($search->{'title'});
902 if ($type eq 'loose') {
903 if ($search->{'author'} ne ''){
904 my @key=split(' ',$search->{'author'});
907 $query="select *,biblio.author,biblio.biblionumber from
909 left join additionalauthors
910 on additionalauthors.biblionumber =biblio.biblionumber
912 ((biblio.author like '$key[0]%' or biblio.author like '% $key[0]%' or
913 additionalauthors.author like '$key[0]%' or additionalauthors.author
918 biblio.author like '$key[$i]%' or biblio.author like '% $key[$i]%' or
919 additionalauthors.author like '$key[$i]%' or additionalauthors.author like '% $key[$i]%'
924 if ($search->{'title'} ne ''){
925 my @key=split(' ',$search->{'title'});
928 $query.= " and (((title like '$key[0]%' or title like '% $key[0]%' or title like '% $key[0]')";
930 $query .= " and (title like '$key[$i]%' or title like '% $key[$i]%' or title like '% $key[$i]')";
933 $query.=") or ((seriestitle like '$key[0]%' or seriestitle like '% $key[0]%' or seriestitle like '% $key[0]')";
934 for ($i=1;$i<$count;$i++){
935 $query.=" and (seriestitle like '$key[$i]%' or seriestitle like '% $key[$i]%')";
937 $query.=") or ((unititle like '$key[0]%' or unititle like '% $key[0]%' or unititle like '% $key[0]')";
938 for ($i=1;$i<$count;$i++){
939 $query.=" and (unititle like '$key[$i]%' or unititle like '% $key[$i]%')";
942 #$query=$query. " and (title like '%$search->{'title'}%'
943 #or seriestitle like '%$search->{'title'}%')";
945 if ($search->{'abstract'} ne ''){
946 $query.= " and (abstract like '%$search->{'abstract'}%')";
948 if ($search->{'date-before'} ne ''){
949 $query.= " and (copyrightdate like '%$search->{'date-before'}%')";
951 $query.=" group by biblio.biblionumber";
953 if ($search->{'title'} ne '') {
954 if ($search->{'ttype'} eq 'exact'){
955 $query="select * from biblio
957 (biblio.title='$search->{'title'}' or (biblio.unititle = '$search->{'title'}'
958 or biblio.unititle like '$search->{'title'} |%' or
959 biblio.unititle like '%| $search->{'title'} |%' or
960 biblio.unititle like '%| $search->{'title'}') or
961 (biblio.seriestitle = '$search->{'title'}' or
962 biblio.seriestitle like '$search->{'title'} |%' or
963 biblio.seriestitle like '%| $search->{'title'} |%' or
964 biblio.seriestitle like '%| $search->{'title'}')
967 my @key=split(' ',$search->{'title'});
970 $query="select biblio.biblionumber,author,title,unititle,notes,abstract,serial,seriestitle,copyrightdate,timestamp,subtitle from biblio
971 left join bibliosubtitle on
972 biblio.biblionumber=bibliosubtitle.biblionumber
974 (((title like '$key[0]%' or title like '% $key[0]%' or title like '% $key[0]')";
976 $query .= " and (title like '$key[$i]%' or title like '% $key[$i]%' or title like '% $key[$i]')";
979 $query.=") or ((subtitle like '$key[0]%' or subtitle like '% $key[0]%' or subtitle like '% $key[0]')";
980 for ($i=1;$i<$count;$i++){
981 $query.=" and (subtitle like '$key[$i]%' or subtitle like '% $key[$i]%' or subtitle like '% $key[$i]')";
983 $query.=") or ((seriestitle like '$key[0]%' or seriestitle like '% $key[0]%' or seriestitle like '% $key[0]')";
984 for ($i=1;$i<$count;$i++){
985 $query.=" and (seriestitle like '$key[$i]%' or seriestitle like '% $key[$i]%')";
987 $query.=") or ((unititle like '$key[0]%' or unititle like '% $key[0]%' or unititle like '% $key[0]')";
988 for ($i=1;$i<$count;$i++){
989 $query.=" and (unititle like '$key[$i]%' or unititle like '% $key[$i]%')";
993 if ($search->{'abstract'} ne ''){
994 $query.= " and (abstract like '%$search->{'abstract'}%')";
996 if ($search->{'date-before'} ne ''){
997 $query.= " and (copyrightdate like '%$search->{'date-before'}%')";
999 } elsif ($search->{'class'} ne ''){
1000 $query="select * from biblioitems,biblio where biblio.biblionumber=biblioitems.biblionumber";
1001 my @temp=split(/\|/,$search->{'class'});
1003 $query.= " and ( itemtype='$temp[0]'";
1004 for (my $i=1;$i<$count;$i++){
1005 $query.=" or itemtype='$temp[$i]'";
1008 if ($search->{'illustrator'} ne ''){
1009 $query.=" and illus like '%".$search->{'illustrator'}."%' ";
1011 if ($search->{'dewey'} ne ''){
1012 $query.=" and biblioitems.dewey like '$search->{'dewey'}%'";
1014 } elsif ($search->{'dewey'} ne ''){
1015 $query="select * from biblioitems,biblio
1016 where biblio.biblionumber=biblioitems.biblionumber
1017 and biblioitems.dewey like '$search->{'dewey'}%'";
1018 } elsif ($search->{'illustrator'} ne '') {
1019 $query="select * from biblioitems,biblio
1020 where biblio.biblionumber=biblioitems.biblionumber
1021 and biblioitems.illus like '%".$search->{'illustrator'}."%'";
1022 } elsif ($search->{'publisher'} ne ''){
1023 $query.= "Select * from biblio,biblioitems where biblio.biblionumber
1024 =biblioitems.biblionumber and (publishercode like '%$search->{'publisher'}%')";
1025 } elsif ($search->{'abstract'} ne ''){
1026 $query.= "Select * from biblio where abstract like '%$search->{'abstract'}%'";
1027 } elsif ($search->{'date-before'} ne ''){
1028 $query.= "Select * from biblio where copyrightdate like '%$search->{'date-before'}%'";
1030 $query .=" group by biblio.biblionumber";
1033 if ($type eq 'subject'){
1034 my @key=split(' ',$search->{'subject'});
1037 $query="select * from bibliosubject, biblioitems where
1038 (bibliosubject.biblionumber = biblioitems.biblionumber) and ( subject like
1039 '$key[0]%' or subject like '% $key[0]%' or subject like '% $key[0]' or subject
1040 like '%($key[0])%')"; while ($i<$count){ $query.=" and (subject like
1041 '$key[$i]%' or subject like '% $key[$i]%' or subject like '% $key[$i]'
1042 or subject like '%($key[$i])%')";
1046 # FIXME - Wouldn't it be better to fix the database so that if a
1047 # book has a subject "NZ", then it also gets added the subject
1049 # This can also be generalized by adding a table of subject
1050 # synonyms to the database: just declare "NZ" to be a synonym for
1051 # "New Zealand", "SF" a synonym for both "Science fiction" and
1052 # "Fantastic fiction", etc.
1054 if (lc($search->{'subject'}) eq 'nz'){
1055 $query.= " or (subject like 'NEW ZEALAND %' or subject like '% NEW ZEALAND %'
1056 or subject like '% NEW ZEALAND' or subject like '%(NEW ZEALAND)%' ) ";
1057 } elsif ( $search->{'subject'} =~ /^nz /i || $search->{'subject'} =~ / nz /i || $search->{'subject'} =~ / nz$/i){
1058 $query=~ s/ nz/ NEW ZEALAND/ig;
1059 $query=~ s/nz /NEW ZEALAND /ig;
1060 $query=~ s/\(nz\)/\(NEW ZEALAND\)/gi;
1063 if ($type eq 'precise'){
1064 if ($search->{'itemnumber'} ne ''){
1065 $query="select * from items,biblio ";
1066 my $search2=uc $search->{'itemnumber'};
1067 $query=$query." where
1068 items.biblionumber=biblio.biblionumber
1069 and barcode='$search2'";
1072 if ($search->{'isbn'} ne ''){
1073 my $search2=uc $search->{'isbn'};
1074 my $query1 = "select * from biblioitems where isbn='$search2'";
1075 my $sth1=$dbh->prepare($query1);
1076 # print STDERR "$query1\n";
1079 while (my $data=$sth1->fetchrow_hashref) {
1080 $query="select * from biblioitems,biblio where
1081 biblio.biblionumber = $data->{'biblionumber'}
1082 and biblioitems.biblionumber = biblio.biblionumber";
1083 my $sth=$dbh->prepare($query);
1085 # FIXME - There's already a $data in this scope.
1086 my $data=$sth->fetchrow_hashref;
1087 my ($dewey, $subclass) = ($data->{'dewey'}, $data->{'subclass'});
1088 # FIXME - The following assumes that the Dewey code is a
1089 # floating-point number. It isn't: it's a string.
1091 ($dewey == 0) && ($dewey='');
1092 ($dewey) && ($dewey.=" $subclass");
1093 $data->{'dewey'}=$dewey;
1094 $results[$i2]=$data;
1095 # $results[$i2]="$data->{'author'}\t$data->{'title'}\t$data->{'biblionumber'}\t$data->{'copyrightdate'}\t$dewey\t$data->{'isbn'}\t$data->{'itemtype'}";
1102 if ($type ne 'precise' && $type ne 'subject'){
1103 if ($search->{'author'} ne ''){
1104 $query .= " order by biblio.author,title";
1106 $query .= " order by title";
1109 if ($type eq 'subject'){
1110 $query .= "group by subject order by subject ";
1113 my $sth=$dbh->prepare($query);
1117 my $limit= $num+$offset;
1118 while (my $data=$sth->fetchrow_hashref){
1119 my $query="select dewey,subclass,publishercode from biblioitems where biblionumber=$data->{'biblionumber'}";
1120 if ($search->{'class'} ne ''){
1121 my @temp=split(/\|/,$search->{'class'});
1123 $query.= " and ( itemtype='$temp[0]'";
1124 for (my $i=1;$i<$count;$i++){
1125 $query.=" or itemtype='$temp[$i]'";
1129 if ($search->{'dewey'} ne ''){
1130 $query.=" and dewey='$search->{'dewey'}' ";
1132 if ($search->{'illustrator'} ne ''){
1133 $query.=" and illus like '%".$search->{'illustrator'}."%' ";
1135 if ($search->{'publisher'} ne ''){
1136 $query.= " and (publishercode like '%$search->{'publisher'}%')";
1138 my $sti=$dbh->prepare($query);
1145 if ($bibitemdata = $sti->fetchrow_hashref()){
1147 $dewey=$bibitemdata->{'dewey'};
1148 $subclass=$bibitemdata->{'subclass'};
1149 $publishercode=$bibitemdata->{'publishercode'};
1151 # print STDERR "$dewey $subclass $publishercode\n";
1152 # FIXME - The Dewey code is a string, not a number.
1154 ($dewey == 0) && ($dewey='');
1155 ($dewey) && ($dewey.=" $subclass");
1156 $data->{'dewey'}=$dewey;
1157 $data->{'publishercode'}=$publishercode;
1160 if ($count > $offset && $count <= $limit){
1169 return($count,@results);
1172 sub updatesearchstats{
1173 my ($dbh,$query)=@_;
1179 @results = &subsearch($env, $subject);
1181 Searches for books that have a subject that exactly matches
1184 C<&subsearch> returns an array of results. Each element of this array
1185 is a string, containing the book's title, author, and biblionumber,
1193 my ($env,$subject)=@_;
1194 my $dbh = C4::Context->dbh;
1195 $subject=$dbh->quote($subject);
1196 my $query="Select * from biblio,bibliosubject where
1197 biblio.biblionumber=bibliosubject.biblionumber and
1198 bibliosubject.subject=$subject group by biblio.biblionumber
1199 order by biblio.title";
1200 my $sth=$dbh->prepare($query);
1205 while (my $data=$sth->fetchrow_hashref){
1206 push @results, $data;
1215 @results = &ItemInfo($env, $biblionumber, $type);
1217 Returns information about books with the given biblionumber.
1219 C<$type> may be either C<intra> or anything else. If it is not set to
1220 C<intra>, then the search will exclude lost, very overdue, and
1225 C<&ItemInfo> returns a list of references-to-hash. Each element
1226 contains a number of keys. Most of them are table items from the
1227 C<biblio>, C<biblioitems>, C<items>, and C<itemtypes> tables in the
1228 Koha database. Other keys include:
1232 =item C<$data-E<gt>{branchname}>
1234 The name (not the code) of the branch to which the book belongs.
1236 =item C<$data-E<gt>{datelastseen}>
1238 This is simply C<items.datelastseen>, except that while the date is
1239 stored in YYYY-MM-DD format in the database, here it is converted to
1240 DD/MM/YYYY format. A NULL date is returned as C<//>.
1242 =item C<$data-E<gt>{datedue}>
1244 =item C<$data-E<gt>{class}>
1246 This is the concatenation of C<biblioitems.classification>, the book's
1247 Dewey code, and C<biblioitems.subclass>.
1249 =item C<$data-E<gt>{ocount}>
1251 I think this is the number of copies of the book available.
1253 =item C<$data-E<gt>{order}>
1255 If this is set, it is set to C<One Order>.
1262 my ($env,$biblionumber,$type) = @_;
1263 my $dbh = C4::Context->dbh;
1264 my $query = "SELECT *,items.notforloan as itemnotforloan FROM items, biblio, biblioitems left join itemtypes on biblioitems.itemtype = itemtypes.itemtype
1265 WHERE items.biblionumber = ?
1266 AND biblioitems.biblioitemnumber = items.biblioitemnumber
1267 AND biblio.biblionumber = items.biblionumber";
1268 if ($type ne 'intra'){
1269 $query .= " and ((items.itemlost<>1 and items.itemlost <> 2)
1270 or items.itemlost is NULL)
1271 and (wthdrawn <> 1 or wthdrawn is NULL)";
1273 $query .= " order by items.dateaccessioned desc";
1275 my $sth=$dbh->prepare($query);
1276 $sth->execute($biblionumber);
1280 while (my $data=$sth->fetchrow_hashref){
1281 my $iquery = "Select * from issues where itemnumber = ? and returndate is null";
1283 my $isth=$dbh->prepare($iquery);
1284 $isth->execute($data->{'itemnumber'});
1285 if (my $idata=$isth->fetchrow_hashref){
1286 $datedue = format_date($idata->{'date_due'});
1288 if ($data->{'itemlost'} eq '2'){
1289 $datedue='Very Overdue';
1291 if ($data->{'itemlost'} eq '1'){
1294 if ($data->{'wthdrawn'} eq '1'){
1295 $datedue="Cancelled";
1297 if ($datedue eq ''){
1298 # $datedue="Available";
1299 my ($restype,$reserves)=CheckReserves($data->{'itemnumber'});
1305 #get branch information.....
1306 my $bquery = "SELECT * FROM branches
1307 WHERE branchcode = '$data->{'holdingbranch'}'";
1308 my $bsth=$dbh->prepare($bquery);
1310 if (my $bdata=$bsth->fetchrow_hashref){
1311 $data->{'branchname'} = $bdata->{'branchname'};
1314 my $class = $data->{'classification'};
1315 my $dewey = $data->{'dewey'};
1317 if ($dewey eq "000.") { $dewey = "";}; # FIXME - "000" is general
1318 # books about computer science
1319 if ($dewey < 10){$dewey='00'.$dewey;}
1320 if ($dewey < 100 && $dewey > 10){$dewey='0'.$dewey;}
1327 $class .= $data->{'subclass'};
1329 # $results[$i]="$data->{'title'}\t$data->{'barcode'}\t$datedue\t$data->{'branchname'}\t$data->{'dewey'}";
1330 # FIXME - If $data->{'datelastseen'} is NULL, perhaps it'd be prettier
1331 # to leave it empty, rather than convert it to "//".
1332 # Also ideally this should use the local format for displaying dates.
1333 my $date=format_date($data->{'datelastseen'});
1334 $data->{'datelastseen'}=$date;
1335 $data->{'datedue'}=$datedue;
1336 $data->{'class'}=$class;
1341 my $query2="Select * from aqorders where biblionumber=$biblionumber";
1342 my $sth2=$dbh->prepare($query2);
1346 if ($data=$sth2->fetchrow_hashref){
1347 $ocount=$data->{'quantity'} - $data->{'quantityreceived'};
1349 $data->{'ocount'}=$ocount;
1350 $data->{'order'}="One Order";
1361 @results = &GetItems($env, $biblionumber);
1363 Returns information about books with the given biblionumber.
1367 C<&GetItems> returns an array of strings. Each element is a
1368 tab-separated list of values: biblioitemnumber, itemtype,
1369 classification, Dewey number, subclass, ISBN, volume, number, and
1372 Itemdata, in turn, is a string of the form
1373 "I<barcode>C<[>I<holdingbranch>C<[>I<flags>" where I<flags> contains
1374 the string C<NFL> if the item is not for loan, and C<LOST> if the item
1380 my ($env,$biblionumber)=@_;
1381 #debug_msg($env,"GetItems");
1382 my $dbh = C4::Context->dbh;
1383 my $query = "Select * from biblioitems where (biblionumber = $biblionumber)";
1384 #debug_msg($env,$query);
1385 my $sth=$dbh->prepare($query);
1387 #debug_msg($env,"executed query");
1390 while (my $data=$sth->fetchrow_hashref) {
1391 #debug_msg($env,$data->{'biblioitemnumber'});
1392 my $dewey = $data->{'dewey'};
1394 my $line = $data->{'biblioitemnumber'}."\t".$data->{'itemtype'};
1395 $line .= "\t$data->{'classification'}\t$dewey";
1396 $line .= "\t$data->{'subclass'}\t$data->{isbn}";
1397 $line .= "\t$data->{'volume'}\t$data->{number}";
1398 my $isth= $dbh->prepare("select * from items where biblioitemnumber = $data->{'biblioitemnumber'}");
1400 while (my $idata = $isth->fetchrow_hashref) {
1401 my $iline = $idata->{'barcode'}."[".$idata->{'holdingbranch'}."[";
1402 if ($idata->{'notforloan'} == 1) {
1405 if ($idata->{'itemlost'} == 1) {
1408 $line .= "\t$iline";
1411 $results[$i] = $line;
1420 $item = &itemdata($barcode);
1422 Looks up the item with the given barcode, and returns a
1423 reference-to-hash containing information about that item. The keys of
1424 the hash are the fields from the C<items> and C<biblioitems> tables in
1431 my $dbh = C4::Context->dbh;
1432 my $query="Select * from items,biblioitems where barcode='$barcode'
1433 and items.biblioitemnumber=biblioitems.biblioitemnumber";
1435 my $sth=$dbh->prepare($query);
1437 my $data=$sth->fetchrow_hashref;
1444 $data = &bibdata($biblionumber, $type);
1446 Returns information about the book with the given biblionumber.
1448 C<$type> is ignored.
1450 C<&bibdata> returns a reference-to-hash. The keys are the fields in
1451 the C<biblio>, C<biblioitems>, and C<bibliosubtitle> tables in the
1454 In addition, C<$data-E<gt>{subject}> is the list of the book's
1455 subjects, separated by C<" , "> (space, comma, space).
1457 If there are multiple biblioitems with the given biblionumber, only
1458 the first one is considered.
1463 my ($bibnum, $type) = @_;
1464 my $dbh = C4::Context->dbh;
1465 my $query = "Select *, biblioitems.notes AS bnotes, biblio.notes
1466 from biblio, biblioitems
1467 left join bibliosubtitle on
1468 biblio.biblionumber = bibliosubtitle.biblionumber
1469 where biblio.biblionumber = ?
1470 and biblioitems.biblionumber = biblio.biblionumber";
1471 my $sth = $dbh->prepare($query);
1472 $sth->execute($bibnum);
1474 $data = $sth->fetchrow_hashref;
1476 $query = "Select * from bibliosubject where biblionumber = ?";
1477 $sth = $dbh->prepare($query);
1478 $sth->execute($bibnum);
1479 while (my $dat = $sth->fetchrow_hashref){
1480 $data->{'subject'} .= "$dat->{'subject'}, ";
1482 chop $data->{'subject'};
1483 chop $data->{'subject'};
1485 $query = "Select * from additionalauthors where biblionumber = ?";
1486 $sth = $dbh->prepare($query);
1487 $sth->execute($bibnum);
1488 while (my $dat = $sth->fetchrow_hashref){
1489 $data->{'additionalauthors'} .= "$dat->{'author'}, ";
1491 chop $data->{'additionalauthors'};
1492 chop $data->{'additionalauthors'};
1499 $itemdata = &bibitemdata($biblioitemnumber);
1501 Looks up the biblioitem with the given biblioitemnumber. Returns a
1502 reference-to-hash. The keys are the fields from the C<biblio>,
1503 C<biblioitems>, and C<itemtypes> tables in the Koha database, except
1504 that C<biblioitems.notes> is given as C<$itemdata-E<gt>{bnotes}>.
1510 my $dbh = C4::Context->dbh;
1511 my $query = "Select *,biblioitems.notes as bnotes from biblio, biblioitems,itemtypes where biblio.biblionumber = biblioitems.biblionumber and biblioitemnumber = ? and biblioitems.itemtype = itemtypes.itemtype";
1512 my $sth = $dbh->prepare($query);
1515 $sth->execute($bibitem);
1517 $data = $sth->fetchrow_hashref;
1525 ($count, $subjects) = &subject($biblionumber);
1527 Looks up the subjects of the book with the given biblionumber. Returns
1528 a two-element list. C<$subjects> is a reference-to-array, where each
1529 element is a subject of the book, and C<$count> is the number of
1530 elements in C<$subjects>.
1536 my $dbh = C4::Context->dbh;
1537 my $query="Select * from bibliosubject where biblionumber=?";
1538 my $sth=$dbh->prepare($query);
1539 $sth->execute($bibnum);
1542 while (my $data=$sth->fetchrow_hashref){
1547 return($i,\@results);
1552 ($count, $authors) = &addauthors($biblionumber);
1554 Looks up the additional authors for the book with the given
1557 Returns a two-element list. C<$authors> is a reference-to-array, where
1558 each element is an additional author, and C<$count> is the number of
1559 elements in C<$authors>.
1565 my $dbh = C4::Context->dbh;
1566 my $query="Select * from additionalauthors where biblionumber=$bibnum";
1567 my $sth=$dbh->prepare($query);
1571 while (my $data=$sth->fetchrow_hashref){
1576 return($i,\@results);
1581 ($count, $subtitles) = &subtitle($biblionumber);
1583 Looks up the subtitles for the book with the given biblionumber.
1585 Returns a two-element list. C<$subtitles> is a reference-to-array,
1586 where each element is a subtitle, and C<$count> is the number of
1587 elements in C<$subtitles>.
1593 my $dbh = C4::Context->dbh;
1594 my $query="Select * from bibliosubtitle where biblionumber=$bibnum";
1595 my $sth=$dbh->prepare($query);
1599 while (my $data=$sth->fetchrow_hashref){
1604 return($i,\@results);
1609 @issues = &itemissues($biblioitemnumber, $biblio);
1611 Looks up information about who has borrowed the bookZ<>(s) with the
1612 given biblioitemnumber.
1614 C<$biblio> is ignored.
1616 C<&itemissues> returns an array of references-to-hash. The keys
1617 include the fields from the C<items> table in the Koha database.
1618 Additional keys include:
1624 If the item is currently on loan, this gives the due date.
1626 If the item is not on loan, then this is either "Available" or
1627 "Cancelled", if the item has been withdrawn.
1631 If the item is currently on loan, this gives the card number of the
1632 patron who currently has the item.
1634 =item C<timestamp0>, C<timestamp1>, C<timestamp2>
1636 These give the timestamp for the last three times the item was
1639 =item C<card0>, C<card1>, C<card2>
1641 The card number of the last three patrons who borrowed this item.
1643 =item C<borrower0>, C<borrower1>, C<borrower2>
1645 The borrower number of the last three patrons who borrowed this item.
1652 my ($bibitem, $biblio)=@_;
1653 my $dbh = C4::Context->dbh;
1654 my $query = "Select * from items where
1655 items.biblioitemnumber = '$bibitem'";
1656 # FIXME - If this function die()s, the script will abort, and the
1657 # user won't get anything; depending on how far the script has
1658 # gotten, the user might get a blank page. It would be much better
1659 # to at least print an error message. The easiest way to do this
1660 # is to set $SIG{__DIE__}.
1661 my $sth = $dbh->prepare($query)
1662 || die $dbh->errstr;
1667 || die $sth->errstr;
1669 while (my $data = $sth->fetchrow_hashref) {
1670 # Find out who currently has this item.
1671 # FIXME - Wouldn't it be better to do this as a left join of
1672 # some sort? Currently, this code assumes that if
1673 # fetchrow_hashref() fails, then the book is on the shelf.
1674 # fetchrow_hashref() can fail for any number of reasons (e.g.,
1675 # database server crash), not just because no items match the
1677 my $query2 = "select * from issues,borrowers
1678 where itemnumber = $data->{'itemnumber'}
1679 and returndate is NULL
1680 and issues.borrowernumber = borrowers.borrowernumber";
1681 my $sth2 = $dbh->prepare($query2);
1684 if (my $data2 = $sth2->fetchrow_hashref) {
1685 $data->{'date_due'} = $data2->{'date_due'};
1686 $data->{'card'} = $data2->{'cardnumber'};
1687 $data->{'borrower'} = $data2->{'borrowernumber'};
1689 if ($data->{'wthdrawn'} eq '1') {
1690 $data->{'date_due'} = 'Cancelled';
1692 $data->{'date_due'} = 'Available';
1698 # Find the last 3 people who borrowed this item.
1699 $query2 = "select * from issues, borrowers
1700 where itemnumber = ?
1701 and issues.borrowernumber = borrowers.borrowernumber
1702 and returndate is not NULL
1703 order by returndate desc,timestamp desc";
1704 $sth2 = $dbh->prepare($query2) || die $dbh->errstr;
1705 $sth2->execute($data->{'itemnumber'}) || die $sth2->errstr;
1706 for (my $i2 = 0; $i2 < 2; $i2++) { # FIXME : error if there is less than 3 pple borrowing this item
1707 if (my $data2 = $sth2->fetchrow_hashref) {
1708 $data->{"timestamp$i2"} = $data2->{'timestamp'};
1709 $data->{"card$i2"} = $data2->{'cardnumber'};
1710 $data->{"borrower$i2"} = $data2->{'borrowernumber'};
1715 $results[$i] = $data;
1725 $item = &itemnodata($env, $dbh, $biblioitemnumber);
1727 Looks up the item with the given biblioitemnumber.
1729 C<$env> and C<$dbh> are ignored.
1731 C<&itemnodata> returns a reference-to-hash whose keys are the fields
1732 from the C<biblio>, C<biblioitems>, and C<items> tables in the Koha
1738 my ($env,$dbh,$itemnumber) = @_;
1739 $dbh = C4::Context->dbh;
1740 my $query="Select * from biblio,items,biblioitems
1741 where items.itemnumber = '$itemnumber'
1742 and biblio.biblionumber = items.biblionumber
1743 and biblioitems.biblioitemnumber = items.biblioitemnumber";
1744 my $sth=$dbh->prepare($query);
1747 my $data=$sth->fetchrow_hashref;
1754 ($count, $borrowers) = &BornameSearch($env, $searchstring, $type);
1756 Looks up patrons (borrowers) by name.
1760 BUGFIX 499: C<$type> is now used to determine type of search.
1761 if $type is "simple", search is performed on the first letter of the
1764 C<$searchstring> is a space-separated list of search terms. Each term
1765 must match the beginning a borrower's surname, first name, or other
1768 C<&BornameSearch> returns a two-element list. C<$borrowers> is a
1769 reference-to-array; each element is a reference-to-hash, whose keys
1770 are the fields of the C<borrowers> table in the Koha database.
1771 C<$count> is the number of elements in C<$borrowers>.
1775 #used by member enquiries from the intranet
1776 #called by member.pl
1778 my ($env,$searchstring,$type)=@_;
1779 my $dbh = C4::Context->dbh;
1780 $searchstring=~ s/\,//g;
1781 $searchstring=~ s/\'/\\\'/g;
1782 my $query = ""; my $count; my @data;
1784 if($type eq "simple") # simple search for one letter only
1786 $query="Select * from borrowers where surname like \"$searchstring%\" order by surname,firstname";
1788 else # advanced search looking in surname, firstname and othernames
1790 @data=split(' ',$searchstring);
1792 $query="Select * from borrowers
1793 where ((surname like \"$data[0]%\" or surname like \"% $data[0]%\"
1794 or firstname like \"$data[0]%\" or firstname like \"% $data[0]%\"
1795 or othernames like \"$data[0]%\" or othernames like \"% $data[0]%\")
1797 for (my $i=1;$i<$count;$i++){
1798 $query=$query." and (".
1799 " firstname like \"$data[$i]%\" or firstname like \"% $data[$i]%\"
1800 or othernames like \"$data[$i]%\" or othernames like \"% $data[$i]%\")";
1803 $query=$query.") or cardnumber = \"$searchstring\"
1804 order by surname,firstname";
1808 my $sth=$dbh->prepare($query);
1812 while (my $data=$sth->fetchrow_hashref){
1813 push(@results,$data);
1817 return ($cnt,\@results);
1822 $borrower = &borrdata($cardnumber, $borrowernumber);
1824 Looks up information about a patron (borrower) by either card number
1825 or borrower number. If $borrowernumber is specified, C<&borrdata>
1826 searches by borrower number; otherwise, it searches by card number.
1828 C<&borrdata> returns a reference-to-hash whose keys are the fields of
1829 the C<borrowers> table in the Koha database.
1834 my ($cardnumber,$bornum)=@_;
1835 $cardnumber = uc $cardnumber;
1836 my $dbh = C4::Context->dbh;
1839 $query="Select * from borrowers where cardnumber='$cardnumber'";
1841 $query="Select * from borrowers where borrowernumber='$bornum'";
1844 my $sth=$dbh->prepare($query);
1846 my $data=$sth->fetchrow_hashref;
1850 } else { # try with firstname
1852 my $sth=$dbh->prepare("select * from borrowers where firstname='$cardnumber'");
1854 my $data=$sth->fetchrow_hashref;
1864 ($count, $issues) = &borrissues($borrowernumber);
1866 Looks up what the patron with the given borrowernumber has borrowed.
1868 C<&borrissues> returns a two-element array. C<$issues> is a
1869 reference-to-array, where each element is a reference-to-hash; the
1870 keys are the fields from the C<issues>, C<biblio>, and C<items> tables
1871 in the Koha database. C<$count> is the number of elements in
1878 my $dbh = C4::Context->dbh;
1880 $query="Select * from issues,biblio,items where borrowernumber='$bornum'
1881 and items.itemnumber=issues.itemnumber
1882 and items.biblionumber=biblio.biblionumber
1883 and issues.returndate is NULL order by date_due";
1885 my $sth=$dbh->prepare($query);
1888 while (my $data = $sth->fetchrow_hashref) {
1889 push @result, $data;
1892 return(scalar(@result), \@result);
1897 ($count, $issues) = &allissues($borrowernumber, $sortkey, $limit);
1899 Looks up what the patron with the given borrowernumber has borrowed,
1900 and sorts the results.
1902 C<$sortkey> is the name of a field on which to sort the results. This
1903 should be the name of a field in the C<issues>, C<biblio>,
1904 C<biblioitems>, or C<items> table in the Koha database.
1906 C<$limit> is the maximum number of results to return.
1908 C<&allissues> returns a two-element array. C<$issues> is a
1909 reference-to-array, where each element is a reference-to-hash; the
1910 keys are the fields from the C<issues>, C<biblio>, C<biblioitems>, and
1911 C<items> tables of the Koha database. C<$count> is the number of
1912 elements in C<$issues>
1917 my ($bornum,$order,$limit)=@_;
1918 my $dbh = C4::Context->dbh;
1920 $query="Select * from issues,biblio,items,biblioitems
1921 where borrowernumber='$bornum' and
1922 items.biblioitemnumber=biblioitems.biblioitemnumber and
1923 items.itemnumber=issues.itemnumber and
1924 items.biblionumber=biblio.biblionumber";
1925 $query.=" order by $order";
1927 $query.=" limit $limit";
1930 my $sth=$dbh->prepare($query);
1934 while (my $data=$sth->fetchrow_hashref){
1939 return($i,\@result);
1944 ($borrowed, $due, $fine) = &borrdata2($env, $borrowernumber);
1946 Returns aggregate data about items borrowed by the patron with the
1947 given borrowernumber.
1951 C<&borrdata2> returns a three-element array. C<$borrowed> is the
1952 number of books the patron currently has borrowed. C<$due> is the
1953 number of overdue items the patron currently has borrowed. C<$fine> is
1954 the total fine currently due by the borrower.
1959 my ($env,$bornum)=@_;
1960 my $dbh = C4::Context->dbh;
1961 my $query="Select count(*) from issues where borrowernumber='$bornum' and
1962 returndate is NULL";
1964 my $sth=$dbh->prepare($query);
1966 my $data=$sth->fetchrow_hashref;
1968 $sth=$dbh->prepare("Select count(*) from issues where
1969 borrowernumber='$bornum' and date_due < now() and returndate is NULL");
1971 my $data2=$sth->fetchrow_hashref;
1973 $sth=$dbh->prepare("Select sum(amountoutstanding) from accountlines where
1974 borrowernumber='$bornum'");
1976 my $data3=$sth->fetchrow_hashref;
1979 return($data2->{'count(*)'},$data->{'count(*)'},$data3->{'sum(amountoutstanding)'});
1982 =item getboracctrecord
1984 ($count, $acctlines, $total) = &getboracctrecord($env, $borrowernumber);
1986 Looks up accounting data for the patron with the given borrowernumber.
1990 (FIXME - I'm not at all sure what this is about.)
1992 C<&getboracctrecord> returns a three-element array. C<$acctlines> is a
1993 reference-to-array, where each element is a reference-to-hash; the
1994 keys are the fields of the C<accountlines> table in the Koha database.
1995 C<$count> is the number of elements in C<$acctlines>. C<$total> is the
1996 total amount outstanding for all of the account lines.
2000 sub getboracctrecord {
2001 my ($env,$params) = @_;
2002 my $dbh = C4::Context->dbh;
2005 my $query= "Select * from accountlines where
2006 borrowernumber=? order by date desc,timestamp desc";
2007 my $sth=$dbh->prepare($query);
2009 $sth->execute($params->{'borrowernumber'});
2011 while (my $data=$sth->fetchrow_hashref){
2012 # if ($data->{'itemnumber'} ne ''){
2013 # $query="Select * from items,biblio where items.itemnumber=
2014 # '$data->{'itemnumber'}' and biblio.biblionumber=items.biblionumber";
2015 # my $sth2=$dbh->prepare($query);
2017 # my $data2=$sth2->fetchrow_hashref;
2021 $acctlines[$numlines] = $data;
2023 $total += $data->{'amountoutstanding'};
2026 return ($numlines,\@acctlines,$total);
2031 ($count, $lcount, $nacount, $fcount, $scount, $lostcount,
2032 $mending, $transit,$ocount) =
2033 &itemcount($env, $biblionumber, $type);
2035 Counts the number of items with the given biblionumber, broken down by
2040 If C<$type> is not set to C<intra>, lost, very overdue, and withdrawn
2041 items will not be counted.
2043 C<&itemcount> returns a nine-element list:
2045 C<$count> is the total number of items with the given biblionumber.
2047 C<$lcount> is the number of items at the Levin branch.
2049 C<$nacount> is the number of items that are neither borrowed, lost,
2050 nor withdrawn (and are therefore presumably on a shelf somewhere).
2052 C<$fcount> is the number of items at the Foxton branch.
2054 C<$scount> is the number of items at the Shannon branch.
2056 C<$lostcount> is the number of lost and very overdue items.
2058 C<$mending> is the number of items at the Mending branch (being
2061 C<$transit> is the number of items at the Transit branch (in transit
2064 C<$ocount> is the number of items that haven't arrived yet
2065 (aqorders.quantity - aqorders.quantityreceived).
2070 # FIXME - There's also a &C4::Biblio::itemcount.
2071 # Since they're all exported, acqui/acquire.pl doesn't compile with -w.
2073 my ($env,$bibnum,$type)=@_;
2074 my $dbh = C4::Context->dbh;
2075 my $query="Select * from items where
2076 biblionumber=$bibnum ";
2077 if ($type ne 'intra'){
2078 $query.=" and ((itemlost <>1 and itemlost <> 2) or itemlost is NULL) and
2079 (wthdrawn <> 1 or wthdrawn is NULL)";
2081 my $sth=$dbh->prepare($query);
2093 while (my $data=$sth->fetchrow_hashref){
2095 my $query2="select * from issues,items where issues.itemnumber=
2096 '$data->{'itemnumber'}' and returndate is NULL
2097 and items.itemnumber=issues.itemnumber and ((items.itemlost <>1 and
2098 items.itemlost <> 2) or items.itemlost is NULL)
2099 and (wthdrawn <> 1 or wthdrawn is NULL)";
2101 my $sth2=$dbh->prepare($query2);
2103 if (my $data2=$sth2->fetchrow_hashref){
2106 if ($data->{'holdingbranch'} eq 'C' || $data->{'holdingbranch'} eq 'LT'){
2109 if ($data->{'holdingbranch'} eq 'F' || $data->{'holdingbranch'} eq 'FP'){
2112 if ($data->{'holdingbranch'} eq 'S' || $data->{'holdingbranch'} eq 'SP'){
2115 if ($data->{'itemlost'} eq '1'){
2118 if ($data->{'itemlost'} eq '2'){
2121 if ($data->{'holdingbranch'} eq 'FM'){
2124 if ($data->{'holdingbranch'} eq 'TR'){
2131 my $query2="Select * from aqorders where biblionumber=$bibnum";
2132 my $sth2=$dbh->prepare($query2);
2134 if (my $data=$sth2->fetchrow_hashref){
2135 $ocount=$data->{'quantity'} - $data->{'quantityreceived'};
2140 return ($count,$lcount,$nacount,$fcount,$scount,$lostcount,$mending,$transit,$ocount);
2145 $counts = &itemcount2($env, $biblionumber, $type);
2147 Counts the number of items with the given biblionumber, broken down by
2152 C<$type> may be either C<intra> or anything else. If it is not set to
2153 C<intra>, then the search will exclude lost, very overdue, and
2156 C<$&itemcount2> returns a reference-to-hash, with the following fields:
2162 The total number of items with this biblionumber.
2166 The number of items on order (aqorders.quantity -
2167 aqorders.quantityreceived).
2171 For each branch that has at least one copy of the book, C<$counts>
2172 will have a key with the branch name, giving the number of copies at
2180 my ($env,$bibnum,$type)=@_;
2181 my $dbh = C4::Context->dbh;
2182 my $query="Select * from items,branches where
2183 biblionumber=? and items.holdingbranch=branches.branchcode";
2184 if ($type ne 'intra'){
2185 $query.=" and ((itemlost <>1 and itemlost <> 2) or itemlost is NULL) and
2186 (wthdrawn <> 1 or wthdrawn is NULL)";
2188 my $sth=$dbh->prepare($query);
2190 $sth->execute($bibnum);
2193 while (my $data=$sth->fetchrow_hashref){
2200 'select * from items
2202 and not ((items.itemlost <>1 and items.itemlost <> 2)
2203 or items.itemlost is NULL)'
2206 'select * from items
2207 where itemnumber=? and not (wthdrawn <> 1 or wthdrawn is NULL)'
2209 'On Loan', "select * from issues,items
2210 where issues.itemnumber=? and returndate is NULL
2211 and items.itemnumber=issues.itemnumber"
2214 my($testlabel, $query2) = @$test;
2216 my $sth2=$dbh->prepare($query2);
2217 $sth2->execute($data->{'itemnumber'});
2219 # FIXME - fetchrow_hashref() can fail for any number of reasons
2220 # (e.g., a database server crash). Perhaps use a left join of some
2222 $status = $testlabel if $sth2->fetchrow_hashref;
2224 last if defined $status;
2226 $status = $data->{'branchname'} unless defined $status;
2229 my $query2="Select * from aqorders where biblionumber=? and
2230 datecancellationprinted is NULL and quantity > quantityreceived";
2231 my $sth2=$dbh->prepare($query2);
2232 $sth2->execute($bibnum);
2233 if (my $data=$sth2->fetchrow_hashref){
2234 $counts{'order'}=$data->{'quantity'} - $data->{'quantityreceived'};
2243 $description = &ItemType($itemtype);
2245 Given an item type code, returns the description for that type.
2250 # FIXME - I'm pretty sure that after the initial setup, the list of
2251 # item types doesn't change very often. Hence, it seems slow and
2252 # inefficient to make yet another database call to look up information
2253 # that'll only change every few months or years.
2255 # Much better, I think, to automatically build a Perl file that can be
2256 # included in those scripts that require it, e.g.:
2257 # @itemtypes = qw( ART BCD CAS CD F ... );
2259 # ART => "Art Prints",
2260 # BCD => "CD-ROM from book",
2261 # CD => "Compact disc (WN)",
2262 # F => "Free Fiction",
2265 # The web server can then run a cron job to rebuild this file from the
2266 # database every hour or so.
2268 # The same thing goes for branches, book funds, book sellers, currency
2269 # rates, printers, stopwords, and perhaps others.
2272 my $dbh = C4::Context->dbh;
2273 my $query="select description from itemtypes where itemtype='$type'";
2274 my $sth=$dbh->prepare($query);
2276 my $dat=$sth->fetchrow_hashref;
2278 return ($dat->{'description'});
2283 ($count, @results) = &bibitems($biblionumber);
2285 Given the biblionumber for a book, C<&bibitems> looks up that book's
2286 biblioitems (different publications of the same book, the audio book
2287 and film versions, etc.).
2289 C<$count> is the number of elements in C<@results>.
2291 C<@results> is an array of references-to-hash; the keys are the fields
2292 of the C<biblioitems> and C<itemtypes> tables of the Koha database. In
2293 addition, C<itemlost> indicates the availability of the item: if it is
2294 "2", then all copies of the item are long overdue; if it is "1", then
2295 all copies are lost; otherwise, there is at least one copy available.
2301 my $dbh = C4::Context->dbh;
2302 my $query = "SELECT biblioitems.*,
2304 MIN(items.itemlost) as itemlost,
2305 MIN(items.dateaccessioned) as dateaccessioned
2306 FROM biblioitems, itemtypes, items
2307 WHERE biblioitems.biblionumber = ?
2308 AND biblioitems.itemtype = itemtypes.itemtype
2309 AND biblioitems.biblioitemnumber = items.biblioitemnumber
2310 GROUP BY items.biblioitemnumber";
2311 my $sth = $dbh->prepare($query);
2314 $sth->execute($bibnum);
2315 while (my $data = $sth->fetchrow_hashref) {
2316 $results[$count] = $data;
2320 return($count, @results);
2325 @barcodes = &barcodes($biblioitemnumber);
2327 Given a biblioitemnumber, looks up the corresponding items.
2329 Returns an array of references-to-hash; the keys are C<barcode> and
2332 The returned items include very overdue items, but not lost ones.
2337 #called from request.pl
2338 my ($biblioitemnumber)=@_;
2339 my $dbh = C4::Context->dbh;
2340 my $query="SELECT barcode, itemlost, holdingbranch FROM items
2341 WHERE biblioitemnumber = ?
2342 AND (wthdrawn <> 1 OR wthdrawn IS NULL)";
2343 my $sth=$dbh->prepare($query);
2344 $sth->execute($biblioitemnumber);
2347 while (my $data=$sth->fetchrow_hashref){
2348 $barcodes[$i]=$data;
2357 ($count, @websites) = &getwebsites($biblionumber);
2359 Looks up the web sites pertaining to the book with the given
2362 C<$count> is the number of elements in C<@websites>.
2364 C<@websites> is an array of references-to-hash; the keys are the
2365 fields from the C<websites> table in the Koha database.
2370 my ($biblionumber) = @_;
2371 my $dbh = C4::Context->dbh;
2372 my $query = "Select * from websites where biblionumber = $biblionumber";
2373 my $sth = $dbh->prepare($query);
2378 while (my $data = $sth->fetchrow_hashref) {
2379 # FIXME - The URL scheme shouldn't be stripped off, at least
2380 # not here, since it's part of the URL, and will be useful in
2381 # constructing a link to the site. If you don't want the user
2382 # to see the "http://" part, strip that off when building the
2384 $data->{'url'} =~ s/^http:\/\///; # FIXME - Leaning toothpick
2386 $results[$count] = $data;
2391 return($count, @results);
2394 =item getwebbiblioitems
2396 ($count, @results) = &getwebbiblioitems($biblionumber);
2398 Given a book's biblionumber, looks up the web versions of the book
2399 (biblioitems with itemtype C<WEB>).
2401 C<$count> is the number of items in C<@results>. C<@results> is an
2402 array of references-to-hash; the keys are the items from the
2403 C<biblioitems> table of the Koha database.
2407 sub getwebbiblioitems {
2408 my ($biblionumber) = @_;
2409 my $dbh = C4::Context->dbh;
2410 my $query = "Select * from biblioitems where biblionumber = $biblionumber
2411 and itemtype = 'WEB'";
2412 my $sth = $dbh->prepare($query);
2417 while (my $data = $sth->fetchrow_hashref) {
2418 $data->{'url'} =~ s/^http:\/\///;
2419 $results[$count] = $data;
2424 return($count, @results);
2425 } # sub getwebbiblioitems
2428 =item breedingsearch
2430 ($count, @results) = &breedingsearch($title,$isbn,$random);
2431 C<$title> contains the title,
2432 C<$isbn> contains isbn or issn,
2433 C<$random> contains the random seed from a z3950 search.
2435 C<$count> is the number of items in C<@results>. C<@results> is an
2436 array of references-to-hash; the keys are the items from the C<marc_breeding> table of the Koha database.
2440 sub breedingsearch {
2441 my ($title,$isbn,$z3950random) = @_;
2442 my $dbh = C4::Context->dbh;
2448 $query = "Select id,file,isbn,title,author from marc_breeding where ";
2450 $query .= "z3950random = \"$z3950random\"";
2453 $query .= "title like \"$title%\"";
2455 if ($title && $isbn) {
2459 $query .= "isbn like \"$isbn%\"";
2462 $sth = $dbh->prepare($query);
2464 while (my $data = $sth->fetchrow_hashref) {
2465 $results[$count] = $data;
2470 return($count, @results);
2471 } # sub breedingsearch
2474 =item getalllanguages
2476 (@languages) = &getalllanguages();
2477 (@languages) = &getalllanguages($theme);
2479 Returns an array of all available languages.
2483 sub getalllanguages {
2488 if ($type eq 'opac') {
2489 $htdocs=C4::Context->config('opachtdocs');
2490 if ($theme and -d "$htdocs/$theme") {
2491 opendir D, "$htdocs/$theme";
2492 foreach my $language (readdir D) {
2493 next if $language=~/^\./;
2494 next if $language eq 'all';
2495 push @languages, $language;
2497 return sort @languages;
2500 foreach my $theme (getallthemes('opac')) {
2501 opendir D, "$htdocs/$theme";
2502 foreach my $language (readdir D) {
2503 next if $language=~/^\./;
2504 next if $language eq 'all';
2505 $lang->{$language}=1;
2508 @languages=keys %$lang;
2509 return sort @languages;
2511 } elsif ($type eq 'intranet') {
2512 $htdocs=C4::Context->config('intrahtdocs');
2513 if ($theme and -d "$htdocs/$theme") {
2514 opendir D, "$htdocs/$theme";
2515 foreach my $language (readdir D) {
2516 next if $language=~/^\./;
2517 next if $language eq 'all';
2518 push @languages, $language;
2520 return sort @languages;
2523 foreach my $theme (getallthemes('opac')) {
2524 opendir D, "$htdocs/$theme";
2525 foreach my $language (readdir D) {
2526 next if $language=~/^\./;
2527 next if $language eq 'all';
2528 $lang->{$language}=1;
2531 @languages=keys %$lang;
2532 return sort @languages;
2536 my $htdocs=C4::Context->config('intrahtdocs');
2537 foreach my $theme (getallthemes('intranet')) {
2538 opendir D, "$htdocs/$theme";
2539 foreach my $language (readdir D) {
2540 next if $language=~/^\./;
2541 next if $language eq 'all';
2542 $lang->{$language}=1;
2545 my $htdocs=C4::Context->config('opachtdocs');
2546 foreach my $theme (getallthemes('opac')) {
2547 opendir D, "$htdocs/$theme";
2548 foreach my $language (readdir D) {
2549 next if $language=~/^\./;
2550 next if $language eq 'all';
2551 $lang->{$language}=1;
2554 @languages=keys %$lang;
2555 return sort @languages;
2561 (@themes) = &getallthemes('opac');
2562 (@themes) = &getallthemes('intranet');
2564 Returns an array of all available themes.
2572 if ($type eq 'intranet') {
2573 $htdocs=C4::Context->config('intrahtdocs');
2575 $htdocs=C4::Context->config('opachtdocs');
2577 opendir D, "$htdocs";
2578 my @dirlist=readdir D;
2579 foreach my $directory (@dirlist) {
2580 -d "$htdocs/$directory/en" and push @themes, $directory;
2589 ($count, @results) = &isbnsearch($isbn,$title);
2591 Given an isbn and/or a title, returns the biblios having it.
2592 Used in acqui.simple, isbnsearch.pl only
2594 C<$count> is the number of items in C<@results>. C<@results> is an
2595 array of references-to-hash; the keys are the items from the
2596 C<biblioitems> table of the Koha database.
2601 my ($isbn,$title) = @_;
2602 my $dbh = C4::Context->dbh;
2608 $query = "Select distinct biblio.* from biblio, biblioitems where
2609 biblio.biblionumber = biblioitems.biblionumber";
2611 $query .= " and isbn=".$dbh->quote($isbn);
2614 $query .= " and title like ".$dbh->quote($title."%");
2616 $sth = $dbh->prepare($query);
2619 while (my $data = $sth->fetchrow_hashref) {
2620 $results[$count] = $data;
2625 return($count, @results);
2630 $branchname = &getbranchname($branchcode);
2632 Given the branch code, the function returns the corresponding
2633 branch name for a comprehensive information display
2639 my ($branchcode) = @_;
2640 my $dbh = C4::Context->dbh;
2641 my $query = "SELECT branchname FROM branches WHERE branchcode = '$branchcode'";
2642 my $sth = $dbh->prepare($query);
2644 my $branchname = $sth->fetchrow();
2647 } # sub getbranchname
2649 =item getborrowercategory
2651 $description = &getborrowercategory($categorycode);
2653 Given the borrower's category code, the function returns the corresponding
2654 description for a comprehensive information display.
2658 sub getborrowercategory
2661 my $dbh = C4::Context->dbh;
2662 my $query = "SELECT description FROM categories WHERE categorycode = '$catcode'";
2663 my $sth = $dbh->prepare($query);
2665 my $description = $sth->fetchrow();
2667 return $description;
2668 } # sub getborrowercategory
2671 END { } # module clean-up code here (global destructor)
2680 Koha Developement team <info@koha.org>