X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=catalogue%2Fsearch.pl;h=d1a3ca259be2ad5744afcbdd1e432b99169aed9f;hb=4a9ea1c6328899a4c36c4ed6ac6f51d948f22230;hp=b0fea2aa565704c78fd1530c72ea50a8b49c71a4;hpb=ee3707d0de8ba0a0e88dcffad31f5b89997b3f5f;p=koha.git diff --git a/catalogue/search.pl b/catalogue/search.pl index b0fea2aa56..d1a3ca259b 100755 --- a/catalogue/search.pl +++ b/catalogue/search.pl @@ -3,6 +3,7 @@ # For documentation try 'perldoc /path/to/search' # # Copyright 2006 LibLime +# Copyright 2010 BibLibre # # This file is part of Koha # @@ -145,7 +146,8 @@ use C4::Auth qw(:DEFAULT get_session); use C4::Search; use C4::Languages qw(getAllLanguages); use C4::Koha; -use C4::VirtualShelves qw(GetRecentShelves); +use C4::Members qw(GetMember); +use C4::VirtualShelves; use POSIX qw(ceil floor); use C4::Branch; # GetBranches @@ -156,7 +158,7 @@ use CGI qw('-no_undef_params'); my $cgi = new CGI; my ($template,$borrowernumber,$cookie); - +my $lang = C4::Templates::getlanguage($cgi, 'intranet'); # decide which template to use my $template_name; my $template_type; @@ -181,6 +183,16 @@ if (C4::Context->preference("marcflavour") eq "UNIMARC" ) { $template->param('UNIMARC' => 1); } +if($cgi->cookie("holdfor")){ + my $holdfor_patron = GetMember('borrowernumber' => $cgi->cookie("holdfor")); + $template->param( + holdfor => $cgi->cookie("holdfor"), + holdfor_surname => $holdfor_patron->{'surname'}, + holdfor_firstname => $holdfor_patron->{'firstname'}, + holdfor_cardnumber => $holdfor_patron->{'cardnumber'}, + ); +} + ## URI Re-Writing # Deprecated, but preserved because it's interesting :-) # The same thing can be accomplished with mod_rewrite in @@ -226,45 +238,51 @@ my $categories = GetBranchCategories(undef,'searchdomain'); $template->param(branchloop => \@branch_loop, searchdomainloop => $categories); -# load the Type stuff # load the Type stuff my $itemtypes = GetItemTypes; # the index parameter is different for item-level itemtypes my $itype_or_itemtype = (C4::Context->preference("item-level_itypes"))?'itype':'itemtype'; -my @itemtypesloop; -my $selected=1; +my @advancedsearchesloop; my $cnt; -my $advanced_search_types = C4::Context->preference("AdvancedSearchTypes"); - -if (!$advanced_search_types or $advanced_search_types eq 'itemtypes') { foreach my $thisitemtype ( sort {$itemtypes->{$a}->{'description'} cmp $itemtypes->{$b}->{'description'} } keys %$itemtypes ) { - my %row =( number=>$cnt++, - ccl => $itype_or_itemtype, +my $advanced_search_types = C4::Context->preference("AdvancedSearchTypes") || "itemtypes"; +my @advanced_search_types = split(/\|/, $advanced_search_types); + +foreach my $advanced_srch_type (@advanced_search_types) { + if ($advanced_srch_type eq 'itemtypes') { + # itemtype is a special case, since it's not defined in authorized values + my @itypesloop; + foreach my $thisitemtype ( sort {$itemtypes->{$a}->{'description'} cmp $itemtypes->{$b}->{'description'} } keys %$itemtypes ) { + my %row =( number=>$cnt++, + ccl => "$itype_or_itemtype,phr", code => $thisitemtype, - selected => $selected, description => $itemtypes->{$thisitemtype}->{'description'}, - count5 => $cnt % 4, imageurl=> getitemtypeimagelocation( 'intranet', $itemtypes->{$thisitemtype}->{'imageurl'} ), ); - $selected = 0 if ($selected) ; - push @itemtypesloop, \%row; - } - $template->param(itemtypeloop => \@itemtypesloop); -} else { - my $advsearchtypes = GetAuthorisedValues($advanced_search_types); - for my $thisitemtype (sort {$a->{'lib'} cmp $b->{'lib'}} @$advsearchtypes) { - my %row =( - number=>$cnt++, - ccl => $advanced_search_types, + push @itypesloop, \%row; + } + my %search_code = ( advanced_search_type => $advanced_srch_type, + code_loop => \@itypesloop ); + push @advancedsearchesloop, \%search_code; + } else { + # covers all the other cases: non-itemtype authorized values + my $advsearchtypes = GetAuthorisedValues($advanced_srch_type); + my @authvalueloop; + for my $thisitemtype (@$advsearchtypes) { + my %row =( + number=>$cnt++, + ccl => $advanced_srch_type, code => $thisitemtype->{authorised_value}, - selected => $selected, description => $thisitemtype->{'lib'}, - count5 => $cnt % 4, - imageurl=> getitemtypeimagelocation( 'intranet', $thisitemtype->{'imageurl'} ), - ); - push @itemtypesloop, \%row; + imageurl => getitemtypeimagelocation( 'intranet', $thisitemtype->{'imageurl'} ), + ); + push @authvalueloop, \%row; + } + my %search_code = ( advanced_search_type => $advanced_srch_type, + code_loop => \@authvalueloop ); + push @advancedsearchesloop, \%search_code; } - $template->param(itemtypeloop => \@itemtypesloop); } +$template->param(advancedsearchesloop => \@advancedsearchesloop); # The following should only be loaded if we're bringing up the advanced search template if ( $template_type eq 'advsearch' ) { @@ -277,15 +295,19 @@ if ( $template_type eq 'advsearch' ) { $template->param(outer_sup_servers_loop => $secondary_servers_loop,); # set the default sorting - my $default_sort_by = C4::Context->preference('defaultSortField')."_".C4::Context->preference('defaultSortOrder') - if (C4::Context->preference('OPACdefaultSortField') && C4::Context->preference('OPACdefaultSortOrder')); - $template->param($default_sort_by => 1); + if ( C4::Context->preference('OPACdefaultSortField') + && C4::Context->preference('OPACdefaultSortOrder') ) { + my $default_sort_by = + C4::Context->preference('defaultSortField') . '_' + . C4::Context->preference('defaultSortOrder'); + $template->param( sort_by => $default_sort_by ); + } # determine what to display next to the search boxes (ie, boolean option # shouldn't appear on the first one, scan indexes should, adding a new # box should only appear on the last, etc. my @search_boxes_array; - my $search_boxes_count = C4::Context->preference("OPACAdvSearchInputCount") || 3; # FIXME: using OPAC sysprefs? + my $search_boxes_count = 3; # begin whith 3 boxes # FIXME: all this junk can be done in TMPL using __first__ and __last__ for (my $i=1;$i<=$search_boxes_count;$i++) { # if it's the first one, don't display boolean option, but show scan indexes @@ -312,16 +334,16 @@ if ( $template_type eq 'advsearch' ) { search_boxes_loop => \@search_boxes_array); # load the language limits (for search) - my $languages_limit_loop = getAllLanguages(); + my $languages_limit_loop = getAllLanguages($lang); $template->param(search_languages_loop => $languages_limit_loop,); - # use the global setting by default - if ( C4::Context->preference("expandedSearchOption") == 1) { - $template->param( expanded_options => C4::Context->preference("expandedSearchOption") ); - } - # but let the user override it - if ( ($cgi->param('expanded_options') == 0) || ($cgi->param('expanded_options') == 1 ) ) { - $template->param( expanded_options => $cgi->param('expanded_options')); + # Expanded search options in advanced search: + # use the global setting by default, but let the user override it + { + my $expanded = $cgi->param('expanded_options'); + $expanded = C4::Context->preference("expandedSearchOption") || 0 + if !defined($expanded) || $expanded !~ /^0|1$/; + $template->param( expanded_options => $expanded ); } $template->param(virtualshelves => C4::Context->preference("virtualshelves")); @@ -342,19 +364,23 @@ my $params = $cgi->Vars; # sort by is used to sort the query # in theory can have more than one but generally there's just one my @sort_by; -my $default_sort_by = C4::Context->preference('defaultSortField')."_".C4::Context->preference('defaultSortOrder') - if (C4::Context->preference('defaultSortField') && C4::Context->preference('defaultSortOrder')); +my $default_sort_by; +if ( C4::Context->preference('defaultSortField') + && C4::Context->preference('defaultSortOrder') ) { + $default_sort_by = + C4::Context->preference('defaultSortField') . '_' + . C4::Context->preference('defaultSortOrder'); +} -@sort_by = split("\0",$params->{'sort_by'}) if $params->{'sort_by'}; +@sort_by = $cgi->param('sort_by'); $sort_by[0] = $default_sort_by unless $sort_by[0]; foreach my $sort (@sort_by) { - $template->param($sort => 1); + $template->param($sort => 1) if $sort; } $template->param('sort_by' => $sort_by[0]); # Use the servers defined, or just search our local catalog(default) -my @servers; -@servers = split("\0",$params->{'server'}) if $params->{'server'}; +my @servers = $cgi->param('server'); unless (@servers) { #FIXME: this should be handled using Context.pm @servers = ("biblioserver"); @@ -362,29 +388,28 @@ unless (@servers) { } # operators include boolean and proximity operators and are used # to evaluate multiple operands -my @operators; -@operators = split("\0",$params->{'op'}) if $params->{'op'}; +my @operators = $cgi->param('op'); # indexes are query qualifiers, like 'title', 'author', etc. They # can be single or multiple parameters separated by comma: kw,right-Truncation -my @indexes; -@indexes = split("\0",$params->{'idx'}); +my @indexes = $cgi->param('idx'); # if a simple index (only one) display the index used in the top search box -if ($indexes[0] && !$indexes[1]) { - $template->param("ms_".$indexes[0] => 1);} +if ($indexes[0] && (!$indexes[1] || $params->{'scan'})) { + my $idx = "ms_".$indexes[0]; + $idx =~ s/\,/comma/g; # template toolkit doesnt like variables with a , in it + $template->param($idx => 1); +} # an operand can be a single term, a phrase, or a complete ccl query -my @operands; -@operands = split("\0",$params->{'q'}) if $params->{'q'}; +my @operands = $cgi->param('q'); # limits are use to limit to results to a pre-defined category such as branch or language -my @limits; -@limits = split("\0",$params->{'limit'}) if $params->{'limit'}; +my @limits = $cgi->param('limit'); if($params->{'multibranchlimit'}) { -push @limits, join(" or ", map { "branch: $_ "} @{GetBranchesInCategory($params->{'multibranchlimit'})}) ; + push @limits, '('.join( " or ", map { "branch: $_ " } @{ GetBranchesInCategory( $params->{'multibranchlimit'} ) } ).')'; } my $available; @@ -416,18 +441,18 @@ if ($params->{'limit-yr'}) { # $ %z3950p will be a hash ref if the indexes are present (advacned search), otherwise undef my $z3950par; my $indexes2z3950 = { - kw=>'title', au=>'author', 'au,phr'=>'author', nb=>'isbn', ns=>'issn', - 'lcn,phr'=>'dewey', su=>'subject', 'su,phr'=>'subject', - ti=>'title', 'ti,phr'=>'title', se=>'title' + kw=>'title', au=>'author', 'au,phr'=>'author', nb=>'isbn', ns=>'issn', + 'lcn,phr'=>'dewey', su=>'subject', 'su,phr'=>'subject', + ti=>'title', 'ti,phr'=>'title', se=>'title' }; for (my $ii = 0; $ii < @operands; ++$ii) { - my $name = $indexes2z3950->{$indexes[$ii]}; - if (defined $name && defined $operands[$ii]) - { - $z3950par ||= {}; - $z3950par->{$name} = $operands[$ii] if !exists $z3950par->{$name}; - } + my $name = $indexes2z3950->{$indexes[$ii]}; + if (defined $name && defined $operands[$ii]) + { + $z3950par ||= {}; + $z3950par->{$name} = $operands[$ii] if !exists $z3950par->{$name}; + } } @@ -447,7 +472,6 @@ my ( $error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit my @results; ## I. BUILD THE QUERY -my $lang = C4::Output::getlanguagecookie($cgi); ( $error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$stopwords_removed,$query_type) = buildQuery(\@operators,\@operands,\@indexes,\@limits,\@sort_by,$scan,$lang); ## parse the query_cgi string and put it into a form suitable for s @@ -456,14 +480,13 @@ my $scan_index_to_use; for my $this_cgi ( split('&',$query_cgi) ) { next unless $this_cgi; - $this_cgi =~ m/(.*=)(.*)/; + $this_cgi =~ m/(.*?)=(.*)/; my $input_name = $1; my $input_value = $2; - $input_name =~ s/=$//; push @query_inputs, { input_name => $input_name, input_value => $input_value }; - if ($input_name eq 'idx') { - $scan_index_to_use = $input_value; # unless $scan_index_to_use; - } + if ($input_name eq 'idx') { + $scan_index_to_use = $input_value; # unless $scan_index_to_use; + } } $template->param ( QUERY_INPUTS => \@query_inputs, scan_index_to_use => $scan_index_to_use ); @@ -500,7 +523,7 @@ if (C4::Context->preference('NoZebra')) { }; } else { eval { - ($error, $results_hashref, $facets) = getRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$query_type,$scan); + ($error, $results_hashref, $facets) = getRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$itemtypes,$query_type,$scan); }; } # This sorts the facets into alphabetical order @@ -524,13 +547,13 @@ for (my $i=0;$i<@servers;$i++) { $hits = $results_hashref->{$server}->{"hits"}; my $page = $cgi->param('page') || 0; my @newresults = searchResults('intranet', $query_desc, $hits, $results_per_page, $offset, $scan, - @{$results_hashref->{$server}->{"RECORDS"}}); + $results_hashref->{$server}->{"RECORDS"}); $total = $total + $results_hashref->{$server}->{"hits"}; ## If there's just one result, redirect to the detail page if ($total == 1) { my $biblionumber = $newresults[0]->{biblionumber}; - my $defaultview = C4::Context->preference('IntranetBiblioDefaultView'); - my $views = { C4::Search::enabled_staff_search_views }; + my $defaultview = C4::Context->preference('IntranetBiblioDefaultView'); + my $views = { C4::Search::enabled_staff_search_views }; if ($defaultview eq 'isbd' && $views->{can_view_ISBD}) { print $cgi->redirect("/cgi-bin/koha/catalogue/ISBDdetail.pl?biblionumber=$biblionumber"); } elsif ($defaultview eq 'marc' && $views->{can_view_MARC}) { @@ -555,14 +578,18 @@ for (my $i=0;$i<@servers;$i++) { $template->param(limit_desc => $limit_desc); $template->param(offset => $offset); $template->param(DisplayMultiPlaceHold => $DisplayMultiPlaceHold); - $template->param (z3950_search_params => C4::Search::z3950_search_args($query_desc)); + $template->param (z3950_search_params => C4::Search::z3950_search_args($query_desc)); if ($query_desc || $limit_desc) { $template->param(searchdesc => 1); } $template->param(stopwords_removed => "@$stopwords_removed") if $stopwords_removed; $template->param(results_per_page => $results_per_page); + # must define a value for size if not present in DB + # in order to avoid problems generated by the default size value in TT + foreach my $line (@newresults) { + if ( not exists $line->{'size'} ) { $line->{'size'} = "" } + } $template->param(SEARCH_RESULTS => \@newresults); - ## FIXME: add a global function for this, it's better than the current global one ## Build the page numbers on the bottom of the page my @page_numbers; @@ -571,7 +598,10 @@ for (my $i=0;$i<@servers;$i++) { # default page number my $current_page_number = 1; $current_page_number = ($offset / $results_per_page + 1) if $offset; - my $previous_page_offset = $offset - $results_per_page unless ($offset - $results_per_page <0); + my $previous_page_offset; + if ( $offset >= $results_per_page ) { + $previous_page_offset = $offset - $results_per_page; + } my $next_page_offset = $offset + $results_per_page; # If we're within the first 10 pages, keep it simple #warn "current page:".$current_page_number; @@ -585,10 +615,14 @@ for (my $i=0;$i<@servers;$i++) { my $this_offset = (($i*$results_per_page)-$results_per_page); # the page number for this page my $this_page_number = $i; - # it should only be highlighted if it's the current page - my $highlight = 1 if ($this_page_number == $current_page_number); # put it in the array - push @page_numbers, { offset => $this_offset, pg => $this_page_number, highlight => $highlight, sort_by => join " ",@sort_by }; + push @page_numbers, + { offset => $this_offset, + pg => $this_page_number, + # it should only be highlighted if it's the current page + highlight => $this_page_number == $current_page_number, + sort_by => join ' ', @sort_by + }; } @@ -599,9 +633,13 @@ for (my $i=0;$i<@servers;$i++) { for (my $i=$current_page_number; $i<=($current_page_number + 20 );$i++) { my $this_offset = ((($i-9)*$results_per_page)-$results_per_page); my $this_page_number = $i-9; - my $highlight = 1 if ($this_page_number == $current_page_number); - if ($this_page_number <= $pages) { - push @page_numbers, { offset => $this_offset, pg => $this_page_number, highlight => $highlight, sort_by => join " ",@sort_by }; + if ( $this_page_number <= $pages ) { + push @page_numbers, + { offset => $this_offset, + pg => $this_page_number, + highlight => $this_page_number == $current_page_number, + sort_by => join ' ', @sort_by + }; } } } @@ -615,7 +653,7 @@ for (my $i=0;$i<@servers;$i++) { # no hits else { $template->param(searchdesc => 1,query_desc => $query_desc,limit_desc => $limit_desc); - $template->param (z3950_search_params => C4::Search::z3950_search_args($z3950par || $query_desc)); + $template->param (z3950_search_params => C4::Search::z3950_search_args($z3950par || $query_desc)); } } # end of the if local @@ -645,6 +683,7 @@ $template->param( total => $total, opacfacets => 1, facets_loop => $facets, + displayFacetCount=> C4::Context->preference('displayFacetCount')||0, scan => $scan, search_error => $error, ); @@ -656,24 +695,13 @@ if ($query_desc || $limit_desc) { # VI. BUILD THE TEMPLATE # Build drop-down list for 'Add To:' menu... - -my $row_count = 10; # FIXME:This probably should be a syspref -my ($pubshelves, $total) = GetRecentShelves(2, $row_count, undef); -my ($barshelves, $total) = GetRecentShelves(1, $row_count, $borrowernumber); - -my @pubshelves = @{$pubshelves}; -my @barshelves = @{$barshelves}; - -if (@pubshelves) { - $template->param( addpubshelves => scalar (@pubshelves)); - $template->param( addpubshelvesloop => @pubshelves); -} - -if (@barshelves) { - $template->param( addbarshelves => scalar (@barshelves)); - $template->param( addbarshelvesloop => @barshelves); -} - - +my ($totalref, $pubshelves, $barshelves)= + C4::VirtualShelves::GetSomeShelfNames($borrowernumber,'COMBO',1); +$template->param( + addbarshelves => $totalref->{bartotal}, + addbarshelvesloop => $barshelves, + addpubshelves => $totalref->{pubtotal}, + addpubshelvesloop => $pubshelves, + ); output_html_with_http_headers $cgi, $cookie, $template->output;