rel_3_0 moved to HEAD
[koha.git] / catalogue / catalogue-search.pl
1 #!/usr/bin/perl
2 use strict;
3
4 use CGI;
5 use C4::Search;
6 use C4::Auth;
7 use C4::Interface::CGI::Output;
8 use C4::Biblio;
9 use C4::Koha;
10 use POSIX qw(ceil floor);
11
12 my $query = new CGI;
13 my $dbh = C4::Context->dbh;
14
15 my $op = $query->param('op'); #show the search form or execute the search
16
17 my $format=$query->param('MARC');
18 my ($template, $borrowernumber, $cookie);
19
20 # get all the common search variables, 
21 my @value=$query->param('value');
22 my @kohafield=$query->param('kohafield');
23 my @and_or=$query->param('and_or');
24 my @relation=$query->param('relation');
25 my $order=$query->param('order');
26 my $reorder=$query->param('reorder');
27 my $number_of_results=$query->param('number_of_results');
28 my $zoom=$query->param('zoom');
29 my $ascend=$query->param('asc');
30 my $searchtype=$query->param('searchtype'); ## this is actual query type
31
32 my @marclist = $query->param('marclist');
33 # collect all the fields ...
34 my %search;
35 my @forminputs;         #this is for the links to navigate among the results
36 my (@searchdesc, %hashdesc,$facetsdesc);        #this is to show the description of the current search
37 my @fields = ('value', 'kohafield', 'and_or', 'relation','order','barcode','biblionumber','itemnumber','asc','from','searchtype');
38
39 ###Collect all the marclist values coming from old Koha MARCdetails
40 ## Although we can not search on all marc fields- if any is matched in Zebra we can use it 
41 my $sth=$dbh->prepare("Select kohafield from koha_attr where tagfield=? and tagsubfield=? and intrashow=1");
42 foreach my $marc (@marclist) {
43                 if ($marc) {
44                 $sth->execute(substr($marc,0,3),substr($marc,3,1));
45                         if ((my $kohafield)=$sth->fetchrow){
46                         push @kohafield,$kohafield;
47                         push @and_or,"\@or";
48                         push @value,@value[0] if @kohafield>1;
49                         push @relation ,"\@attr 5=1";
50                         }
51                 }
52 }
53 #### Now   normal search routine
54 foreach my $field (@fields) {
55         $search{$field} = $query->param($field);
56         my @fieldvalue = $query->param($field);
57         foreach my $fvalue (@fieldvalue) {
58                 push @forminputs, { field=>$field ,value=> $fvalue} unless ($field eq 'reorder');
59                 
60           }
61 }
62 ## Build the query for facets as well
63  for (my $i=0;$i<@value;$i++){
64 $facetsdesc.="&value=".$value[$i];
65 $facetsdesc.="&kohafield=".$kohafield[$i];
66 $facetsdesc.="&relation=".$relation[$i];
67 $facetsdesc.="&and_or=".$and_or[$i];
68 }
69 $facetsdesc.="&order=".$order;
70 $hashdesc{'query'} = join " , ", @value;
71 push @searchdesc,\%hashdesc;
72
73
74 ############################################################################
75 if ($op eq "do_search"){
76  
77 #this fields is just to allow the user come back to the search form with all the values  previously entered
78 $search{'search_type'} = $query->param('search_type');# this is the panel type
79 push @forminputs, {field => 'search_type', value => $search{'search_type'}};
80
81
82         ($template, $borrowernumber, $cookie)
83                 = get_template_and_user({template_name => "catalogue/catalogue_searchresults.tmpl",
84                                          query => $query,
85                                          type => "intranet",
86                                          authnotrequired => 1,
87         });
88
89         $search{'from'} = 'intranet';
90         $search{'borrowernumber'} = $borrowernumber;
91         $search{'remote_IP'} = $query->remote_addr();
92         $search{'remote_URL'} = $query->url(-query=>1);
93         $search{'searchdesc'} = \@searchdesc;
94         $template->param(FORMINPUTS => \@forminputs);
95         $template->param(reorder => $query->param('reorder'));
96         $template->param(facetsdesc=>$facetsdesc);
97         # do the searchs ....
98          $number_of_results = 10 unless $number_of_results;
99         my $startfrom=$query->param('startfrom');
100         ($startfrom) || ($startfrom=0);
101 my ($count,@results,$facets);
102 if (!$zoom){
103 ## using sql search for barcode,biblionumber or itemnumber only useful for libraian interface
104         ($count, @results) =sqlsearch($dbh,\%search);
105 }else{
106 my $sortorder=$order.$ascend if $order;
107  ($count,$facets,@results) =ZEBRAsearch_kohafields(\@kohafield,\@value, \@relation,$sortorder, \@and_or, 1,$reorder,$startfrom, $number_of_results,"intranet",$searchtype);
108 }
109         if ( $count eq "error"){
110         $template->param(error =>1);
111         goto "show";
112         }
113         my $num = scalar(@results) - 1;
114 if ( $count == 1){
115     # if its a barcode search by definition we will only have one result.
116     # And if we have a result
117     # lets jump straight to the detail.pl page
118         if ($format eq '1') {
119     print $query->redirect("/cgi-bin/koha/catalogue/MARCdetail.pl?type=intra&biblionumber=$results[0]->{'biblionumber'}");
120         }else{
121     print $query->redirect("/cgi-bin/koha/catalogue/detail.pl?type=intra&biblionumber=$results[0]->{'biblionumber'}");
122         }
123 }
124         # sorting out which results to display.
125         # the result number to star to show
126         $template->param(startfrom => $startfrom);
127         $template->param(beginning => $startfrom+1);
128         # the result number to end to show
129         ($startfrom+$num<=$count) ? ($template->param(endat => $startfrom+$num+1)) : ($template->param(endat => $count));
130         # the total results searched
131         $template->param(numrecords => $count);
132         $template->param(FORMINPUTS => \@forminputs );
133         $template->param(searchdesc => \@searchdesc );
134         $template->param(SEARCH_RESULTS => \@results,
135                         facets_loop => $facets,
136                         );
137
138         #this is to show the images numbers to navigate among the results, if it has to show the number highlighted or not
139         my $numbers;
140         @$numbers = ();
141         my $pg = 1;
142         if (defined($query->param('pg'))) {
143                 $pg = $query->param('pg');
144         }
145         my $start = 0;
146         
147         $start = ($pg - 1) * $number_of_results;
148         my $pages = ceil($count / $number_of_results);
149         my $total_pages = ceil($count / $number_of_results);
150
151         if ($pg > 1) {
152                 my $url = $pg - 1;
153                 push @$numbers, { number => "&lt;&lt;", 
154                                               highlight => 0 , 
155                                               startfrom => 0, 
156                                               pg => '1' };
157                 push @$numbers, { number => "&lt;", 
158                                                   highlight => 0 , forminputs=>\@forminputs,
159                                                   startfrom => ($url-1)*$number_of_results+1, 
160                                                   pg => $url };
161         }
162         my $current_ten = $pg / 10;
163         if ($current_ten == 0) {
164                  $current_ten = 0.1;           # In case it´s in ten = 0
165         } 
166         my $from = $current_ten * 10; # Calculate the initial page
167         my $end_ten = $from + 9;
168         my $to;
169         if ($pages > $end_ten) {
170                 $to = $end_ten;
171         } else {
172                 $to = $pages;
173         }
174         for (my $i = $from; $i <= $to ; $i++) {
175                 if ($i == $pg) {   
176                         if ($count > $number_of_results) {
177                                 push @$numbers, { number => $i, 
178                                                                   highlight => 1 , forminputs=>\@forminputs,
179                                                                   startfrom => ($i-1)*$number_of_results , 
180                                                                   pg => $i };
181                         }
182                 } else {
183                         push @$numbers, { number => $i, 
184                                                           highlight => 0 , forminputs=>\@forminputs,
185                                                           startfrom => ($i-1)*$number_of_results , 
186                                                           pg => $i };
187                 }
188         }                                                       
189         if ($pg < $pages) {
190                 my $url = $pg + 1;
191                 push @$numbers, { number => "&gt;", 
192                                                   highlight => 0 , forminputs=>\@forminputs,
193                                                   startfrom => ($url-1)*$number_of_results, 
194                                                   pg => $url };
195                 push @$numbers, { number => "&gt;&gt;", 
196                                                   highlight => 0 , forminputs=>\@forminputs,
197                                                   startfrom => ($total_pages-1)*$number_of_results, 
198                                                   pg => $total_pages};
199         }
200 #       push @$numbers,{forminputs=>@forminputs};
201         $template->param(numbers =>$numbers,
202                         );
203         #show the virtual shelves
204         #my $results = &GetShelfList($borrowernumber);
205         #$template->param(shelvescount => scalar(@{$results}));
206         #$template->param(shelves => $results);
207
208 ########
209 if ($format eq '1') {
210         $template->param(script => "catalogue/MARCdetail.pl");
211 }else{
212         $template->param(script => "catalogue/detail.pl");
213 }
214
215 }else{ ## No search yet
216 ($template, $borrowernumber, $cookie)
217                 = get_template_and_user({template_name => "catalogue/catalogue_search.tmpl",
218                                         query => $query,
219                                         type => "intranet",
220                                         authnotrequired => 1,
221                                 });
222 #show kohafields
223         my $kohafield = $query->param('kohafield');
224         my ($fieldcount,@kohafields)=getkohafields();
225         foreach my $row (@kohafields) {
226                 if ($kohafield eq $row->{'kohafield'}) {
227                         $row->{'sel'} = 1;
228                 }
229         }
230         $template->param(kohafields => \@kohafields);
231 ##show sorting fields
232 my @sorts;
233  $order=$query->param('order');
234         foreach my $sort (@kohafields) {
235             if ($sort->{sorts}){
236                 push @sorts,$sort;
237                 if ($order eq $sort->{'kohafield'}) {
238                         $sort->{'sel'} = 1;
239                 }
240            }
241         }
242         $template->param(sorts => \@sorts);
243 # load the branches
244 my @branches = GetallBranches();
245 $template->param(branchloop => \@branches,);
246
247 # load the itemtypes 
248 my $itemtypes=GetItemTypes();
249 my (@item_type_loop);
250 foreach my $thisitemtype (sort keys %$itemtypes) {
251     my %row =(itemtype => $thisitemtype,
252                  description => $itemtypes->{$thisitemtype}->{'description'},
253             );
254     push @item_type_loop, \%row;
255 }
256
257 $template->param(itemtypeloop=>\@item_type_loop,);
258 my $search_type = $query->param('search_type');
259         if ((!$search_type) || ($search_type eq 'zoom'))  {
260                 $template->param(zoom_search => 1);
261         } else{
262                 $template->param(sql_search => 1);
263         } 
264 }
265
266 show:
267 output_html_with_http_headers $query, $cookie, $template->output();
268