# Script to perform searching
# For documentation try 'perldoc /path/to/search'
#
-# $Header$
-#
# Copyright 2006 LibLime
#
# This file is part of Koha
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
-# You should have received a copy of the GNU General Public License along with
-# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-# Suite 330, Boston, MA 02111-1307 USA
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
=head1 NAME
not cover in detail.
=head3 1. Building Query Strings
-
+
There are several types of queries needed in the process of search and retrieve:
=over
=cut
use strict; # always use
+#use warnings; FIXME - Bug 2505
## STEP 1. Load things that are used in both search page and
# results page and decide which template to load, operations
## load Koha modules
use C4::Context;
use C4::Output;
-use C4::Auth;
+use C4::Auth qw(:DEFAULT get_session);
use C4::Search;
-use C4::Languages; # getAllLanguages
+use C4::Languages qw(getAllLanguages);
use C4::Koha;
+use C4::VirtualShelves qw(GetRecentShelves);
use POSIX qw(ceil floor);
use C4::Branch; # GetBranches
+my $DisplayMultiPlaceHold = C4::Context->preference("DisplayMultiPlaceHold");
# create a new CGI object
# FIXME: no_undef_params needs to be tested
use CGI qw('-no_undef_params');
my $branches = GetBranches();
my @branch_loop;
-for my $branch_hash (sort keys %$branches) {
- push @branch_loop, {value => "$branch_hash" , branchname => $branches->{$branch_hash}->{'branchname'}, };
+# we need to know the borrower branch code to set a default branch
+my $borrowerbranchcode = C4::Context->userenv->{'branch'};
+
+for my $branch_hash (sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } keys %$branches) {
+ # if independantbranches is activated, set the default branch to the borrower branch
+ my $selected = (C4::Context->preference("independantbranches") and ($borrowerbranchcode eq $branch_hash)) ? 1 : undef;
+ push @branch_loop, {value => "$branch_hash" , branchname => $branches->{$branch_hash}->{'branchname'}, selected => $selected};
}
my $categories = GetBranchCategories(undef,'searchdomain');
$template->param(branchloop => \@branch_loop, searchdomainloop => $categories);
-# load the itemtypes
+# 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 $cnt;
-my $imgdir = getitemtypeimagesrc();
-foreach my $thisitemtype ( sort {$itemtypes->{$a}->{'description'} cmp $itemtypes->{$b}->{'description'} } keys %$itemtypes ) {
+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++,
- imageurl=> $itemtypes->{$thisitemtype}->{'imageurl'}?($imgdir."/".$itemtypes->{$thisitemtype}->{'imageurl'}):"",
+ ccl => $itype_or_itemtype,
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,
+ code => $thisitemtype->{authorised_value},
+ selected => $selected,
+ description => $thisitemtype->{'lib'},
+ count5 => $cnt % 4,
+ imageurl=> getitemtypeimagelocation( 'intranet', $thisitemtype->{'imageurl'} ),
);
- $selected = 0 if ($selected) ;
- push @itemtypesloop, \%row;
+ push @itemtypesloop, \%row;
+ }
+ $template->param(itemtypeloop => \@itemtypesloop);
}
-$template->param(itemtypeloop => \@itemtypesloop);
-
-# load the ccodes
-# my ($ccodecount,@ccode_loop) = GetCcodes();
-# $template->param(ccodeloop=>\@ccode_loop,);
-
-# load the languages ( for switching from one template to another )
-$template->param(languages_loop => getTranslatedLanguages('intranet','prog'));
# The following should only be loaded if we're bringing up the advanced search template
if ( $template_type eq 'advsearch' ) {
my $primary_servers_loop;# = displayPrimaryServers();
$template->param(outer_servers_loop => $primary_servers_loop,);
- my $secondary_servers_loop;# = displaySecondaryServers();
+ my $secondary_servers_loop;
$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);
+
# 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: should be a syspref
+ my $search_boxes_count = C4::Context->preference("OPACAdvSearchInputCount") || 3; # FIXME: using OPAC sysprefs?
+ # 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
if ($i==1) {
- push @search_boxes_array,
- {
- scan_index => 1,
- };
-
+ push @search_boxes_array, {scan_index => 1};
}
# if it's the last one, show the 'add field' box
elsif ($i==$search_boxes_count) {
$template->param( expanded_options => $cgi->param('expanded_options'));
}
+ $template->param(virtualshelves => C4::Context->preference("virtualshelves"));
+
output_html_with_http_headers $cgi, $cookie, $template->output;
exit;
}
my @indexes;
@indexes = split("\0",$params->{'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);}
+
+
# an operand can be a single term, a phrase, or a complete ccl query
my @operands;
@operands = split("\0",$params->{'q'}) if $params->{'q'};
#FIXME: Should return a error to the user, incorect date format specified
}
+# convert indexes and operands to corresponding parameter names for the z3950 search
+# $ %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'
+};
+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};
+ }
+}
+
+
# Params that can only have one value
my $scan = $params->{'scan'};
my $count = C4::Context->preference('numSearchResults') || 20;
my @results;
## 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);
+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 <input>s
my @query_inputs;
+my $scan_index_to_use;
+
for my $this_cgi ( split('&',$query_cgi) ) {
next unless $this_cgi;
$this_cgi =~ m/(.*=)(.*)/;
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;
+ }
}
-$template->param ( QUERY_INPUTS => \@query_inputs );
+$template->param ( QUERY_INPUTS => \@query_inputs,
+ scan_index_to_use => $scan_index_to_use );
## parse the limit_cgi string and put it into a form suitable for <input>s
my @limit_inputs;
if (C4::Context->preference('NoZebra')) {
$query=~s/yr(:|=)\s*([\d]{1,4})-([\d]{1,4})/(yr>=$2 and yr<=$3)/g;
$simple_query=~s/yr\s*(:|=)([\d]{1,4})-([\d]{1,4})/(yr>=$2 and yr<=$3)/g;
- warn $query;
+ # warn $query;
eval {
($error, $results_hashref, $facets) = NZgetRecords($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,$query_type,$scan);
};
}
+# This sorts the facets into alphabetical order
+if ($facets) {
+ foreach my $f (@$facets) {
+ $f->{facets} = [ sort { uc($a->{facet_title_value}) cmp uc($b->{facet_title_value}) } @{ $f->{facets} } ];
+ }
+}
if ($@ || $error) {
$template->param(query_error => $error.$@);
-
output_html_with_http_headers $cgi, $cookie, $template->output;
exit;
}
-# FIXME: This belongs in tools/ not in the primary search results page
-my $op=$cgi->param("operation");
-if ($op eq "bulkedit"){
- my ($countchanged,$listunchanged)=
- ModBiblios($results_hashref->{'biblioserver'}->{"RECORDS"},
- $params->{"tagsubfield"},
- $params->{"inputvalue"},
- $params->{"targetvalue"},
- $params->{"test"}
- );
- $template->param(bulkeditresults=>1,
- tagsubfield=>$params->{"tagsubfield"},
- inputvalue=>$params->{"inputvalue"},
- targetvalue=>$params->{"targetvalue"},
- countchanged=>$countchanged,
- countunchanged=>scalar(@$listunchanged),
- listunchanged=>$listunchanged);
-
- if (C4::Context->userenv->{'flags'}==1 ||(C4::Context->userenv->{'flags'} & ( 2**9 ) )){
- #Edit Catalogue Permissions
- $template->param(bulkedit => 1);
- $template->param(tagsubfields=>GetManagedTagSubfields());
- }
-}
-
# At this point, each server has given us a result set
# now we build that set for template display
my @sup_results_array;
if ($server =~/biblioserver/) { # this is the local bibliographic server
$hits = $results_hashref->{$server}->{"hits"};
my $page = $cgi->param('page') || 0;
- my @newresults = searchResults( $query_desc,$hits,$results_per_page,$offset,@{$results_hashref->{$server}->{"RECORDS"}});
+ my @newresults = searchResults('intranet', $query_desc, $hits, $results_per_page, $offset, $scan,
+ @{$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 };
+ 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}) {
+ print $cgi->redirect("/cgi-bin/koha/catalogue/MARCdetail.pl?biblionumber=$biblionumber");
+ } elsif ($defaultview eq 'labeled_marc' && $views->{can_view_labeledMARC}) {
+ print $cgi->redirect("/cgi-bin/koha/catalogue/labeledMARCdetail.pl?biblionumber=$biblionumber");
+ } else {
+ print $cgi->redirect("/cgi-bin/koha/catalogue/detail.pl?biblionumber=$biblionumber");
+ }
+ exit;
+ }
+
+
if ($hits) {
$template->param(total => $hits);
my $limit_cgi_not_availablity = $limit_cgi;
$template->param(query_cgi => $query_cgi);
$template->param(query_desc => $query_desc);
$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));
if ($query_desc || $limit_desc) {
$template->param(searchdesc => 1);
}
}
}
+
# now, show twenty pages, with the current one smack in the middle
else {
for (my $i=$current_page_number; $i<=($current_page_number + 20 );$i++) {
push @page_numbers, { offset => $this_offset, pg => $this_page_number, highlight => $highlight, sort_by => join " ",@sort_by };
}
}
-
}
# FIXME: no previous_page_offset when pages < 2
$template->param( PAGE_NUMBERS => \@page_numbers,
previous_page_offset => $previous_page_offset) unless $pages < 2;
$template->param( next_page_offset => $next_page_offset) unless $pages eq $current_page_number;
}
+
+
# 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));
}
+
} # end of the if local
# asynchronously search the authority server
'link' => "&idx=an&q=".$marc_record_object->field('001')->as_string(),
};
}
- my $servername = $server;
- push @sup_results_array, { servername => $servername,
+ push @sup_results_array, { servername => $server,
inner_sup_results_loop => \@inner_sup_results_array} if @inner_sup_results_array;
}
# FIXME: can add support for other targets as needed here
$template->param(searchdesc => 1);
}
-## Now let's find out if we have any supplemental data to show the user
-# and in the meantime, save the current query for statistical purposes, etc.
-my $koha_spsuggest; # a flag to tell if we've got suggestions coming from Koha
-my @koha_spsuggest; # place we store the suggestions to be returned to the template as LOOP
-my $phrases = $query_desc;
-my $ipaddress;
-
-if ( C4::Context->preference("kohaspsuggest") ) {
- my ($suggest_host, $suggest_dbname, $suggest_user, $suggest_pwd) = split(':', C4::Context->preference("kohaspsuggest"));
- eval {
- my $koha_spsuggest_dbh;
- # FIXME: this needs to be moved to Context.pm
- eval {
- $koha_spsuggest_dbh=DBI->connect("DBI:mysql:$suggest_dbname:$suggest_host","$suggest_user","$suggest_pwd");
- };
- if ($@) {
- warn "can't connect to spsuggest db";
- }
- else {
- my $koha_spsuggest_insert = "INSERT INTO phrase_log(phr_phrase,phr_resultcount,phr_ip) VALUES(?,?,?)";
- my $koha_spsuggest_query = "SELECT display FROM distincts WHERE strcmp(soundex(suggestion), soundex(?)) = 0 order by soundex(suggestion) limit 0,5";
- my $koha_spsuggest_sth = $koha_spsuggest_dbh->prepare($koha_spsuggest_query);
- $koha_spsuggest_sth->execute($phrases);
- while (my $spsuggestion = $koha_spsuggest_sth->fetchrow_array) {
- $spsuggestion =~ s/(:|\/)//g;
- my %line;
- $line{spsuggestion} = $spsuggestion;
- push @koha_spsuggest,\%line;
- $koha_spsuggest = 1;
- }
+# VI. BUILD THE TEMPLATE
- # Now save the current query
- $koha_spsuggest_sth=$koha_spsuggest_dbh->prepare($koha_spsuggest_insert);
- #$koha_spsuggest_sth->execute($phrases,$results_per_page,$ipaddress);
- $koha_spsuggest_sth->finish;
+# Build drop-down list for 'Add To:' menu...
- $template->param( koha_spsuggest => $koha_spsuggest ) unless $hits;
- $template->param( SPELL_SUGGEST => \@koha_spsuggest,
- );
- }
- };
- if ($@) {
- warn "Kohaspsuggest failure:".$@;
- }
+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);
}
-# VI. BUILD THE TEMPLATE
+if (@barshelves) {
+ $template->param( addbarshelves => scalar (@barshelves));
+ $template->param( addbarshelvesloop => @barshelves);
+}
+
+
+
output_html_with_http_headers $cgi, $cookie, $template->output;