X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=catalogue%2Fsearch.pl;h=e4ca11aff15c44396ba96631707eeabd924d7309;hb=2b90ea2cb0e5e976de7ddef0151ae83d8ac578e6;hp=c3ec804b468a78128edce689be57dfebf74d9e22;hpb=d58f2cfaf6a3951c1c224019ec911cc9ce387877;p=srvgit diff --git a/catalogue/search.pl b/catalogue/search.pl index c3ec804b46..e4ca11aff1 100755 --- a/catalogue/search.pl +++ b/catalogue/search.pl @@ -146,13 +146,17 @@ use C4::Auth qw(:DEFAULT get_session); use C4::Search; use C4::Languages qw(getLanguages); use C4::Koha; -use C4::Members qw(GetMember); -use C4::VirtualShelves; use URI::Escape; use POSIX qw(ceil floor); -use C4::Branch; # GetBranches use C4::Search::History; +use Koha::ItemTypes; +use Koha::LibraryCategories; +use Koha::Patrons; +use Koha::SearchEngine::Search; +use Koha::SearchEngine::QueryBuilder; +use Koha::Virtualshelves; + use URI::Escape; my $DisplayMultiPlaceHold = C4::Context->preference("DisplayMultiPlaceHold"); @@ -161,11 +165,10 @@ my $DisplayMultiPlaceHold = C4::Context->preference("DisplayMultiPlaceHold"); use CGI qw('-no_undef_params' -utf8 ); my $cgi = new CGI; -my ($template,$borrowernumber,$cookie); # decide which template to use my $template_name; my $template_type; -my @params = $cgi->param("limit"); +my @params = $cgi->multi_param("limit"); if ((@params>=1) || ($cgi->param("q")) || ($cgi->param('multibranchlimit')) || ($cgi->param('limit-yr')) ) { $template_name = 'catalogue/results.tt'; } @@ -193,62 +196,33 @@ if (C4::Context->preference("IntranetNumbersPreferPhrase")) { } if($cgi->cookie("holdfor")){ - my $holdfor_patron = GetMember('borrowernumber' => $cgi->cookie("holdfor")); + my $holdfor_patron = Koha::Patrons->find( $cgi->cookie("holdfor") ); $template->param( holdfor => $cgi->cookie("holdfor"), - holdfor_surname => $holdfor_patron->{'surname'}, - holdfor_firstname => $holdfor_patron->{'firstname'}, - holdfor_cardnumber => $holdfor_patron->{'cardnumber'}, + 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 -# a more elegant way -# -#my $rewrite_flag; -#my $uri = $cgi->url(-base => 1); -#my $relative_url = $cgi->url(-relative=>1); -#$uri.="/".$relative_url."?"; -#warn "URI:$uri"; -#my @cgi_params_list = $cgi->param(); -#my $url_params = $cgi->Vars; -# -#for my $each_param_set (@cgi_params_list) { -# $uri.= join "", map "\&$each_param_set=".$_, split("\0",$url_params->{$each_param_set}) if $url_params->{$each_param_set}; -#} -#warn "New URI:$uri"; -# Only re-write a URI if there are params or if it already hasn't been re-written -#unless (($cgi->param('r')) || (!$cgi->param()) ) { -# print $cgi->redirect( -uri=>$uri."&r=1", -# -cookie => $cookie); -# exit; -#} +# get biblionumbers stored in the cart +my @cart_list; + +if($cgi->cookie("intranet_bib_list")){ + my $cart_list = $cgi->cookie("intranet_bib_list"); + @cart_list = split(/\//, $cart_list); +} # load the branches -my $branches = GetBranches(); - -# Populate branch_loop with all branches sorted by their name. If -# IndependentBranches is activated, set the default branch to the borrower -# branch, except for superlibrarian who need to search all libraries. -my $user = C4::Context->userenv; -my @branch_loop = map { - { - value => $_, - branchname => $branches->{$_}->{branchname}, - selected => $user->{branch} eq $_ && C4::Branch::onlymine(), - } -} sort { - $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} -} keys %$branches; - -my $categories = GetBranchCategories('searchdomain'); - -$template->param(branchloop => \@branch_loop, searchdomainloop => $categories); +my $categories = Koha::LibraryCategories->search( { categorytype => 'searchdomain' }, { order_by => [ 'categorytype', 'categorycode' ] } ); + +$template->param( + selected_branchcode => ( C4::Context->IsSuperLibrarian ? C4::Context->userenv : '' ), + searchdomainloop => $categories +); # load the Type stuff -my $itemtypes = GetItemTypes; +my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; # the index parameter is different for item-level itemtypes my $itype_or_itemtype = (C4::Context->preference("item-level_itypes"))?'itype':'itemtype'; my @advancedsearchesloop; @@ -294,6 +268,9 @@ foreach my $advanced_srch_type (@advanced_search_types) { } } $template->param(advancedsearchesloop => \@advancedsearchesloop); +my $types = C4::Context->preference("AdvancedSearchTypes") || "itemtypes"; +my $advancedsearchesloop = prepare_adv_search_types($types); +$template->param(advancedsearchesloop => $advancedsearchesloop); # The following should only be loaded if we're bringing up the advanced search template if ( $template_type eq 'advsearch' ) { @@ -383,7 +360,7 @@ if ( C4::Context->preference('defaultSortField') . C4::Context->preference('defaultSortOrder'); } -@sort_by = $cgi->param('sort_by'); +@sort_by = $cgi->multi_param('sort_by'); $sort_by[0] = $default_sort_by unless $sort_by[0]; foreach my $sort (@sort_by) { $template->param($sort => 1) if $sort; @@ -391,7 +368,7 @@ foreach my $sort (@sort_by) { $template->param('sort_by' => $sort_by[0]); # Use the servers defined, or just search our local catalog(default) -my @servers = $cgi->param('server'); +my @servers = $cgi->multi_param('server'); unless (@servers) { #FIXME: this should be handled using Context.pm @servers = ("biblioserver"); @@ -399,11 +376,11 @@ unless (@servers) { } # operators include boolean and proximity operators and are used # to evaluate multiple operands -my @operators = map uri_unescape($_), $cgi->param('op'); +my @operators = map uri_unescape($_), $cgi->multi_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 = map uri_unescape($_), $cgi->param('idx'); +my @indexes = map uri_unescape($_), $cgi->multi_param('idx'); # if a simple index (only one) display the index used in the top search box if ($indexes[0] && (!$indexes[1] || $params->{'scan'})) { @@ -413,16 +390,18 @@ if ($indexes[0] && (!$indexes[1] || $params->{'scan'})) { } # an operand can be a single term, a phrase, or a complete ccl query -my @operands = map uri_unescape($_), $cgi->param('q'); +my @operands = map uri_unescape($_), $cgi->multi_param('q'); # limits are use to limit to results to a pre-defined category such as branch or language -my @limits = map uri_unescape($_), $cgi->param('limit'); -my @nolimits = map uri_unescape($_), $cgi->param('nolimit'); +my @limits = map uri_unescape($_), $cgi->multi_param('limit'); +my @nolimits = map uri_unescape($_), $cgi->multi_param('nolimit'); my %is_nolimit = map { $_ => 1 } @nolimits; @limits = grep { not $is_nolimit{$_} } @limits; if($params->{'multibranchlimit'}) { - my $multibranch = '('.join( " or ", map { "branch: $_ " } @{ GetBranchesInCategory( $params->{'multibranchlimit'} ) } ).')'; + my $library_category = Koha::LibraryCategories->find( $params->{multibranchlimit} ); + my @libraries = $library_category->libraries; + my $multibranch = '('.join( " or ", map { 'branch: ' . $_->id } @libraries ) .')'; push @limits, $multibranch if ($multibranch ne '()'); } @@ -438,12 +417,7 @@ $template->param(available => $available); my $limit_yr; my $limit_yr_value; if ($params->{'limit-yr'}) { - if ($params->{'limit-yr'} =~ /\d{4}-\d{4}/) { - my ($yr1,$yr2) = split(/-/, $params->{'limit-yr'}); - $limit_yr = "yr,st-numeric,ge=$yr1 and yr,st-numeric,le=$yr2"; - $limit_yr_value = "$yr1-$yr2"; - } - elsif ($params->{'limit-yr'} =~ /\d{4}/) { + if ($params->{'limit-yr'} =~ /\d{4}/) { $limit_yr = "yr,st-numeric=$params->{'limit-yr'}"; $limit_yr_value = $params->{'limit-yr'}; } @@ -481,16 +455,26 @@ my $hits; my $expanded_facet = $params->{'expand'}; # Define some global variables -my ( $error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$stopwords_removed,$query_type); +my ( $error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$query_type); -my @results; +my $builder = Koha::SearchEngine::QueryBuilder->new( + { index => $Koha::SearchEngine::BIBLIOS_INDEX } ); +my $searcher = Koha::SearchEngine::Search->new( + { index => $Koha::SearchEngine::BIBLIOS_INDEX } ); ## I. BUILD THE QUERY -( $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); +( + $error, $query, $simple_query, $query_cgi, + $query_desc, $limit, $limit_cgi, $limit_desc, + $query_type + ) + = $builder->build_query_compat( \@operators, \@operands, \@indexes, \@limits, + \@sort_by, $scan, $lang ); ## parse the query_cgi string and put it into a form suitable for s my @query_inputs; my $scan_index_to_use; +my $scan_search_term_to_use; for my $this_cgi ( split('&',$query_cgi) ) { next unless $this_cgi; @@ -501,9 +485,13 @@ for my $this_cgi ( split('&',$query_cgi) ) { if ($input_name eq 'idx') { $scan_index_to_use = $input_value; # unless $scan_index_to_use; } + if ($input_name eq 'q') { + $scan_search_term_to_use = Encode::decode_utf8( uri_unescape( $input_value )); + } } $template->param ( QUERY_INPUTS => \@query_inputs, - scan_index_to_use => $scan_index_to_use ); + scan_index_to_use => $scan_index_to_use, + scan_search_term_to_use => $scan_search_term_to_use ); ## parse the limit_cgi string and put it into a form suitable for s my @limit_inputs; @@ -525,19 +513,17 @@ $template->param ( LIMIT_INPUTS => \@limit_inputs ); ## II. DO THE SEARCH AND GET THE RESULTS my $total; # the total results for the whole set my $facets; # this object stores the faceted results that display on the left-hand of the results page -my @results_array; my $results_hashref; eval { - ($error, $results_hashref, $facets) = getRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$itemtypes,$query_type,$scan); + my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; + ( $error, $results_hashref, $facets ) = $searcher->search_compat( + $query, $simple_query, \@sort_by, \@servers, + $results_per_page, $offset, $expanded_facet, undef, + $itemtypes, $query_type, $scan + ); }; -# This sorts the facets into alphabetical order -if ($facets) { - foreach my $f (@$facets) { - $f->{facets} = [ sort { uc($a->{facet_label_value}) cmp uc($b->{facet_label_value}) } @{ $f->{facets} } ]; - } -} if ($@ || $error) { $template->param(query_error => $error.$@); output_html_with_http_headers $cgi, $cookie, $template->output; @@ -614,12 +600,15 @@ for (my $i=0;$i<@servers;$i++) { 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'} = "" } + # while we're checking each line, see if item is in the cart + if ( grep {$_ eq $line->{'biblionumber'}} @cart_list) { + $line->{'incart'} = 1; + } } $template->param(SEARCH_RESULTS => \@newresults); ## FIXME: add a global function for this, it's better than the current global one @@ -746,14 +735,108 @@ if ($query_desc || $limit_desc) { # VI. BUILD THE TEMPLATE -# Build drop-down list for 'Add To:' menu... -my ($totalref, $pubshelves, $barshelves)= - C4::VirtualShelves::GetSomeShelfNames($borrowernumber,'COMBO',1); +my $some_private_shelves = Koha::Virtualshelves->get_some_shelves( + { + borrowernumber => $borrowernumber, + add_allowed => 1, + category => 1, + } +); +my $some_public_shelves = Koha::Virtualshelves->get_some_shelves( + { + borrowernumber => $borrowernumber, + add_allowed => 1, + category => 2, + } +); + + $template->param( - addbarshelves => $totalref->{bartotal}, - addbarshelvesloop => $barshelves, - addpubshelves => $totalref->{pubtotal}, - addpubshelvesloop => $pubshelves, - ); + add_to_some_private_shelves => $some_private_shelves, + add_to_some_public_shelves => $some_public_shelves, +); output_html_with_http_headers $cgi, $cookie, $template->output; + + +=head2 prepare_adv_search_types + + my $type = C4::Context->preference("AdvancedSearchTypes") || "itemtypes"; + my @advanced_search_types = prepare_adv_search_types($type); + +Different types can be searched for in the advanced search. This takes the +system preference that defines these types and parses it into an arrayref for +the template. + +"itemtypes" is handled specially, as itemtypes aren't an authorised value. +It also accounts for the "item-level_itypes" system preference. + +=cut + +sub prepare_adv_search_types { + my ($types) = @_; + + my @advanced_search_types = split( /\|/, $types ); + + # the index parameter is different for item-level itemtypes + my $itype_or_itemtype = + ( C4::Context->preference("item-level_itypes") ) ? 'itype' : 'itemtype'; + my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_localization->unblessed } }; + + my ( $cnt, @result ); + foreach my $advanced_srch_type (@advanced_search_types) { + $advanced_srch_type =~ s/^\s*//; + $advanced_srch_type =~ s/\s*$//; + 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}->{'translated_description'} + cmp $itemtypes->{$b}->{'translated_description'} + } keys %$itemtypes + ) + { + my %row = ( + number => $cnt++, + ccl => "$itype_or_itemtype,phr", + code => $thisitemtype, + description => $itemtypes->{$thisitemtype}->{'translated_description'}, + imageurl => getitemtypeimagelocation( + 'intranet', $itemtypes->{$thisitemtype}->{'imageurl'} + ), + ); + push @itypesloop, \%row; + } + my %search_code = ( + advanced_search_type => $advanced_srch_type, + code_loop => \@itypesloop + ); + push @result, \%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}, + description => $thisitemtype->{'lib'}, + imageurl => getitemtypeimagelocation( + 'intranet', $thisitemtype->{'imageurl'} + ), + ); + push @authvalueloop, \%row; + } + my %search_code = ( + advanced_search_type => $advanced_srch_type, + code_loop => \@authvalueloop + ); + push @result, \%search_code; + } + } + return \@result; +}