--- loncom/interface/lonsearchcat.pm 2003/06/06 02:24:49 1.176
+++ loncom/interface/lonsearchcat.pm 2004/06/28 15:55:09 1.230
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Search Catalog
#
-# $Id: lonsearchcat.pm,v 1.176 2003/06/06 02:24:49 www Exp $
+# $Id: lonsearchcat.pm,v 1.230 2004/06/28 15:55:09 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -48,7 +48,7 @@ described at http://www.lon-capa.org.
lonsearchcat presents the user with an interface to search the LON-CAPA
digital library. lonsearchcat also initiates the execution of a search
by sending the search parameters to LON-CAPA servers. The progress of
-search (on a server basis) is displayed to the user in a seperate window.
+search (on a server basis) is displayed to the user in a separate window.
=head1 Internals
@@ -59,20 +59,8 @@ search (on a server basis) is displayed
###############################################################################
###############################################################################
-###############################################################################
-## ##
-## ORGANIZATION OF THIS PERL MODULE ##
-## ##
-## 1. Modules used by this module ##
-## 2. Variables used throughout the module ##
-## 3. handler subroutine called via Apache and mod_perl ##
-## 4. Other subroutines ##
-## ##
-###############################################################################
-
package Apache::lonsearchcat;
-# ------------------------------------------------- modules used by this module
use strict;
use Apache::Constants qw(:common :http);
use Apache::lonnet();
@@ -82,111 +70,60 @@ use Text::Query;
use GDBM_File;
use Apache::loncommon();
use Apache::lonmysql();
-
-# ---------------------------------------- variables used throughout the module
-
-######################################################################
-######################################################################
-
-=pod
-
-=item Global variables
-
-=over 4
-
-=item $importbutton
-
-button to take the select results and go to group sorting
-
-=item %groupsearch_db
-
-Database hash used to save values for the groupsearch RAT interface.
-
-=item $diropendb
-
-The full path to the (temporary) search database file. This is set and
-used in &handler() and is also used in &output_results().
-
-=item %Views
-
-Hash which associates an output view description with the function
-that produces it. Adding a new view type should be as easy as
-adding a line to the definition of this hash and making sure the function
-takes the proper parameters.
-
-=item $bodytag
-
-LON-CAPA standard body tag, gotten from &Apache::lonnet::bodytag.
-No title, no table, just a
tag.
-
-=back
-
-=cut
+use Apache::lonmeta;
+use Apache::lonhtmlcommon;
+use Apache::lonlocal;
+use LONCAPA::lonmetadata();
+use HTML::Entities();
+use Parse::RecDescent;
######################################################################
######################################################################
-
-# -- dynamically rendered interface components
-my $importbutton; # button to take the selected results and go to group sorting
-
-# -- miscellaneous variables
-my %groupsearch_db; # database hash
-my $diropendb = ""; # db file
-# View Description Function Pointer
-my %Views = ("Detailed Citation View" => \&detailed_citation_view,
- "Summary View" => \&summary_view,
- "Fielded Format" => \&fielded_format_view,
- "XML/SGML" => \&xml_sgml_view,
- "Compact View" => \&compact_view);
-my %persistent_db;
-my $hidden_fields;
-my $bodytag;
-
-#
-# For course search
-#
-my %alreadyseen;
-my $hashtied;
-my %hash;
-my $totalfound;
-
+##
+## Global variables
+##
######################################################################
######################################################################
+my %groupsearch_db; # Database hash used to save values for the
+ # groupsearch RAT interface.
+my %persistent_db; # gdbm hash which holds data which is supposed to
+ # persist across calls to lonsearchcat.pm
-=pod
+# The different view modes and associated functions
-=item &handler() - main handler invoked by httpd child
-
-=item Variables
-
-=over 4
-
-=item $hidden
-
-holds 'hidden' html forms
-
-=item $scrout
-
-string that holds portions of the screen output
-
-=back
-
-=cut
+my %Views = ("detailed" => \&detailed_citation_view,
+ "summary" => \&summary_view,
+ "fielded" => \&fielded_format_view,
+ "xml" => \&xml_sgml_view,
+ "compact" => \&compact_view);
######################################################################
######################################################################
sub handler {
my $r = shift;
+# &set_defaults();
#
+ # set form defaults
+ #
+ my $hidden_fields;# Hold all the hidden fields used to keep track
+ # of the search system state
+ my $importbutton; # button to take the selected results and go to group
+ # sorting
+ my $diropendb; # The full path to the (temporary) search database file.
+ # This is set and used in &handler() and is also used in
+ # &output_results().
+ my $bodytag; # LON-CAPA standard body tag, gotten from
+ # &Apache::lonnet::bodytag.
+ # No title, no table, just a tag.
my $loaderror=&Apache::lonnet::overloaderror($r);
if ($loaderror) { return $loaderror; }
-
+ #
my $closebutton; # button that closes the search window
# This button is different for the RAT compared to
# normal invocation.
#
- $r->content_type('text/html');
+ &Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
return OK if $r->header_only;
##
@@ -199,7 +136,7 @@ sub handler {
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
['catalogmode','launch','acts','mode','form','element','pause',
'phase','persistent_db_id','table','start','show',
- 'cleargroupsort']);
+ 'cleargroupsort','titleelement']);
##
## The following is a trick - we wait a few seconds if asked to so
## the daemon running the search can get ahead of the daemon
@@ -207,15 +144,15 @@ sub handler {
## this once, so the pause indicator is deleted
##
if (exists($ENV{'form.pause'})) {
- sleep(3);
+ sleep(1);
delete($ENV{'form.pause'});
}
##
## Initialize global variables
##
my $domain = $r->dir_config('lonDefDomain');
- $diropendb= "/home/httpd/perl/tmp/".&Apache::lonnet::escape($domain).
- "\_".&Apache::lonnet::escape($ENV{'user.name'})."_searchcat.db";
+ $diropendb= "/home/httpd/perl/tmp/".
+ "$ENV{'user.domain'}_$ENV{'user.name'}_searchcat.db";
#
# set the name of the persistent database
# $ENV{'form.persistent_db_id'} can only have digits in it.
@@ -230,11 +167,34 @@ sub handler {
'_'.&Apache::lonnet::escape($ENV{'user.name'}).
'_'.$ENV{'form.persistent_db_id'}.'_persistent_search.db';
##
- if (! &get_persistent_form_data($persistent_db_file)) {
- if ($ENV{'form.phase'} =~ /(run_search|results)/) {
- &Apache::lonnet::logthis("lonsearchcat:Unable to recover data ".
- "from $persistent_db_file");
- $r->print(<'/adm/searchcat?'.
+ 'catalogmode='.$ENV{'form.catalogmode'}.
+ '&launch='.$ENV{'form.launch'}.
+ '&mode='.$ENV{'form.mode'},
+ text=>"Course and Catalog Search",
+ target=>'_top',
+ bug=>'Searching',});
+ } else {
+ &Apache::lonhtmlcommon::add_breadcrumb
+ ({href=>'/adm/searchcat?'.
+ 'catalogmode='.$ENV{'form.catalogmode'}.
+ '&launch='.$ENV{'form.launch'}.
+ '&mode='.$ENV{'form.mode'},
+ text=>"Catalog Search",
+ target=>'_top',
+ bug=>'Searching',});
+ }
+ #
+ if ($ENV{'form.phase'} !~ m/(basic|adv|course)_search/) {
+ if (! &get_persistent_form_data($persistent_db_file)) {
+ if ($ENV{'form.phase'} =~ /(run_search|results)/) {
+ &Apache::lonnet::logthis('lonsearchcat:'.
+ 'Unable to recover data from '.
+ $persistent_db_file);
+ $r->print(<LON-CAPA Search Error
$bodytag
@@ -243,8 +203,11 @@ error and has been logged. Please alert
END
- return OK;
+ return OK;
+ }
}
+ } else {
+ &clean_up_environment();
}
##
## Clear out old values from groupsearch database
@@ -271,20 +234,19 @@ END
$hidden_fields = ''."\n";
if (exists($ENV{'form.catalogmode'})) {
- $hidden_fields .= ''."\n";
+ $hidden_fields .= &hidden_field('catalogmode');
}
if (exists($ENV{'form.form'})) {
- $hidden_fields .= ''."\n";
+ $hidden_fields .= &hidden_field('form');
}
if (exists($ENV{'form.element'})) {
- $hidden_fields .= ''."\n";
+ $hidden_fields .= &hidden_field('element');
+ }
+ if (exists($ENV{'form.titleelement'})) {
+ $hidden_fields .= &hidden_field('titleelement');
}
if (exists($ENV{'form.mode'})) {
- $hidden_fields .= ''."\n";
+ $hidden_fields .= &hidden_field('mode');
}
##
## Configure dynamic components of interface
@@ -326,15 +288,41 @@ END
}
$ENV{'form.phase'} = 'disp_basic' if (! exists($ENV{'form.phase'}));
$ENV{'form.show'} = 20 if (! exists($ENV{'form.show'}));
+ #
+ $ENV{'form.searchmode'} = 'basic' if (! exists($ENV{'form.searchmode'}));
+ if ($ENV{'form.phase'} eq 'adv_search' ||
+ $ENV{'form.phase'} eq 'disp_adv') {
+ $ENV{'form.searchmode'} = 'advanced';
+ } elsif ($ENV{'form.phase'} eq 'course_search') {
+ $ENV{'form.searchmode'} = 'course_search';
+ }
+ #
+ if ($ENV{'form.searchmode'} eq 'advanced') {
+ &Apache::lonhtmlcommon::add_breadcrumb
+ ({href=>'/adm/searchcat?phase=disp_adv&'.
+ 'catalogmode='.$ENV{'form.catalogmode'}.
+ '&launch='.$ENV{'form.launch'}.
+ '&mode='.$ENV{'form.mode'},
+ text=>"Advanced Search",
+ bug=>'Searching',});
+ } elsif ($ENV{'form.searchmode'} eq 'course search') {
+ &Apache::lonhtmlcommon::add_breadcrumb
+ ({href=>'/adm/searchcat?phase=disp_adv&'.
+ 'catalogmode='.$ENV{'form.catalogmode'}.
+ '&launch='.$ENV{'form.launch'}.
+ '&mode='.$ENV{'form.mode'},
+ text=>"Course Search",
+ bug=>'Searching',});
+ }
##
## Switch on the phase
##
if ($ENV{'form.phase'} eq 'disp_basic') {
- &print_basic_search_form($r,$closebutton);
+ &print_basic_search_form($r,$closebutton,$hidden_fields);
} elsif ($ENV{'form.phase'} eq 'disp_adv') {
- &print_advanced_search_form($r,$closebutton);
+ &print_advanced_search_form($r,$closebutton,$hidden_fields);
} elsif ($ENV{'form.phase'} eq 'results') {
- &display_results($r,$importbutton,$closebutton);
+ &display_results($r,$importbutton,$closebutton,$diropendb);
} elsif ($ENV{'form.phase'} =~ /^(sort|run_search)$/) {
my ($query,$customquery,$customshow,$libraries,$pretty_string) =
&get_persistent_data($persistent_db_file,
@@ -350,12 +338,35 @@ END
&course_search($r);
} elsif(($ENV{'form.phase'} eq 'basic_search') ||
($ENV{'form.phase'} eq 'adv_search')) {
- $ENV{'form.searchmode'} = 'basic';
- if ($ENV{'form.phase'} eq 'adv_search') {
- $ENV{'form.searchmode'} = 'advanced';
+ #
+ # We are running a search, try to parse it
+ my ($query,$customquery,$customshow,$libraries) =
+ (undef,undef,undef,undef);
+ my $pretty_string;
+ if ($ENV{'form.phase'} eq 'basic_search') {
+ ($query,$pretty_string,$libraries) =
+ &parse_basic_search($r,$closebutton,$hidden_fields);
+ return OK if (! defined($query));
+ &make_persistent({ basicexp => $ENV{'form.basicexp'}},
+ $persistent_db_file);
+ } else { # Advanced search
+ ($query,$customquery,$customshow,$libraries,$pretty_string)
+ = &parse_advanced_search($r,$closebutton,$hidden_fields);
+ return OK if (! defined($query));
}
+ &make_persistent({ query => $query,
+ customquery => $customquery,
+ customshow => $customshow,
+ libraries => $libraries,
+ pretty_string => $pretty_string },
+ $persistent_db_file);
+ #
# Set up table
if (! defined(&create_results_table())) {
+ my $errorstring=&Apache::lonmysql::get_error();
+ &Apache::lonnet::logthis('lonsearchcat.pm: Unable to create '.
+ 'needed table. lonmysql error:'.
+ $errorstring);
$r->print(<Search Error
$bodytag
@@ -377,34 +388,65 @@ Unable to properly store search informat
END
return OK;
}
- #
- # We are running a search
- my ($query,$customquery,$customshow,$libraries) =
- (undef,undef,undef,undef);
- my $pretty_string;
- if ($ENV{'form.phase'} eq 'basic_search') {
- ($query,$pretty_string) = &parse_basic_search($r,$closebutton);
- } else { # Advanced search
- ($query,$customquery,$customshow,$libraries,$pretty_string)
- = &parse_advanced_search($r,$closebutton);
- return OK if (! defined($query));
- }
- &make_persistent({ query => $query,
- customquery => $customquery,
- customshow => $customshow,
- libraries => $libraries,
- pretty_string => $pretty_string },
- $persistent_db_file);
##
## Print out the frames interface
##
- &print_frames_interface($r);
+ if (defined($query)) {
+ &print_frames_interface($r);
+ }
}
return OK;
}
+#
+# The mechanism used to store values away and retrieve them does not
+# handle the case of missing environment variables being significant.
+#
+# This routine sets non existant checkbox form elements to ''.
+#
+sub clean_up_environment {
+ if ($ENV{'form.phase'} eq 'basic_search') {
+ if (! exists($ENV{'form.related'})) {
+ $ENV{'form.related'} = '';
+ }
+ if (! exists($ENV{'form.domains'})) {
+ $ENV{'form.domains'} = '';
+ }
+ } elsif ($ENV{'form.phase'} eq 'adv_search') {
+ foreach my $field ('title','keywords','notes',
+ 'abstract','standards','mime') {
+ if (! exists($ENV{'form.'.$field.'_related'})) {
+ $ENV{'form.'.$field.'_related'} = '';
+ }
+ }
+ } elsif ($ENV{'form.phase'} eq 'course_search') {
+ if (! exists($ENV{'form.crsrelated'})) {
+ $ENV{'form.crsrelated'} = '';
+ }
+ }
+}
+
+sub hidden_field {
+ my ($name,$value) = @_;
+ if (! defined($value)) {
+ $value = $ENV{'form.'.$name};
+ }
+ return ''.$/;
+}
+
######################################################################
######################################################################
+##
+## Course Search
+##
+######################################################################
+######################################################################
+{ # Scope the course search to avoid global variables
+#
+# Variables For course search
+my %alreadyseen;
+my %hash;
+my $totalfound;
sub course_search {
my $r=shift;
@@ -415,54 +457,39 @@ sub course_search {
if ($ENV{'form.crsrelated'}) {
($search_string,@New_Words) = &related_version($ENV{'form.courseexp'});
if (@New_Words) {
- $pretty_search_string .= " with related words: @New_Words.";
+ $pretty_search_string .= ' '.&mt("with related words").": @New_Words.";
} else {
- $pretty_search_string .= " with no related words.";
+ $pretty_search_string .= ' '.&mt('with no related words').".";
}
}
my $fulltext=$ENV{'form.crsfulltext'};
my @allwords=($search_string,@New_Words);
$totalfound=0;
$r->print('LON-CAPA Course Search'.
- $bodytag.$pretty_search_string);
+ $bodytag.'
'.$pretty_search_string.'
');
$r->rflush();
# ======================================================= Go through the course
- $hashtied=0;
- undef %alreadyseen;
- %alreadyseen=();
+ undef %alreadyseen;
+ %alreadyseen=();
my $c=$r->connection;
- &tiehash();
- foreach (keys %hash) {
- if ($c->aborted()) { last; }
- if (($_=~/^src\_(.+)$/) && (!$alreadyseen{$hash{$_}})) {
- &checkonthis($r,$hash{$_},0,$hash{'title_'.$1},$fulltext,@allwords);
- }
- }
- &untiehash();
+ if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.".db",
+ &GDBM_READER(),0640)) {
+ foreach (keys %hash) {
+ if ($c->aborted()) { last; }
+ if (($_=~/^src\_(.+)$/) && (!$alreadyseen{$hash{$_}})) {
+ &checkonthis($r,$hash{$_},0,$hash{'title_'.$1},$fulltext,
+ @allwords);
+ }
+ }
+ untie(%hash);
+ }
unless ($totalfound) {
- $r->print('
No resources found.
');
+ $r->print('
'.&mt('No resources found').'.
');
}
# =================================================== Done going through course
$r->print('