--- loncom/interface/lonsearchcat.pm 2002/06/25 15:08:59 1.129 +++ loncom/interface/lonsearchcat.pm 2004/05/05 17:29:06 1.223 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Search Catalog # -# $Id: lonsearchcat.pm,v 1.129 2002/06/25 15:08:59 matthew Exp $ +# $Id: lonsearchcat.pm,v 1.223 2004/05/05 17:29:06 matthew Exp $ # # Copyright Michigan State University Board of Trustees # @@ -25,14 +25,6 @@ # # http://www.lon-capa.org/ # -# YEAR=2001 -# 3/8, 3/12, 3/13, 3/14, 3/15, 3/19 Scott Harrison -# 3/20, 3/21, 3/22, 3/26, 3/27, 4/2, 8/15, 8/24, 8/25 Scott Harrison -# 10/12,10/14,10/15,10/16,11/28,11/29,12/10,12/12,12/16 Scott Harrison -# YEAR=2002 -# 1/17 Scott Harrison -# 6/17 Matthew Hall -# ############################################################################### ############################################################################### @@ -40,7 +32,7 @@ =head1 NAME -lonsearchcat +lonsearchcat - LONCAPA Search Interface =head1 SYNOPSIS @@ -56,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 @@ -67,245 +59,619 @@ 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); +use Apache::Constants qw(:common :http); use Apache::lonnet(); use Apache::File(); use CGI qw(:standard); use Text::Query; use GDBM_File; use Apache::loncommon(); - -# ---------------------------------------- variables used throughout the module +use Apache::lonmysql(); +use Apache::lonmeta; +use Apache::lonhtmlcommon; +use Apache::lonlocal; +use LONCAPA::lonmetadata(); +use HTML::Entities(); ###################################################################### ###################################################################### - -=pod - -=item Global variables - -=over 4 - -=item $closebutton - -button that closes the search window - -=item $importbutton - -button to take the selecte results and go to group sorting - -=item %hash - -The ubiquitous database hash - -=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(). - -=back - -=cut - -###################################################################### -###################################################################### - -# -- dynamically rendered interface components -my $closebutton; # button that closes the search window -my $importbutton; # button to take the selected results and go to group sorting - -# -- miscellaneous variables -my %hash; # database hash -my $diropendb = ""; # db file - +## +## 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 - -=item &handler() - main handler invoked by httpd child - -=item Variables - -=over 4 - -=item $hidden +# The different view modes and associated functions -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; - untie %hash; +# &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. - $r->content_type('text/html'); + 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. + # + &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK if $r->header_only; - - my $domain = $r->dir_config('lonDefDomain'); - $diropendb= "/home/httpd/perl/tmp/".&Apache::lonnet::escape($domain). - "\_".&Apache::lonnet::escape($ENV{'user.name'})."_searchcat.db"; - + ## + ## Prevent caching of the search interface window. Hopefully this means + ## we will get the launch=1 passed in a little more. + &Apache::loncommon::no_cache($r); + ## + ## Pick up form fields passed in the links. + ## &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['catalogmode','launch','acts','mode','form','element', - 'reqinterface']); + ['catalogmode','launch','acts','mode','form','element','pause', + 'phase','persistent_db_id','table','start','show', + '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 + ## printing the results. We only need (theoretically) to do + ## this once, so the pause indicator is deleted + ## + if (exists($ENV{'form.pause'})) { + sleep(1); + delete($ENV{'form.pause'}); + } ## - ## Clear out old values from database + ## Initialize global variables ## - if ($ENV{'form.launch'} eq '1') { - if (tie(%hash,'GDBM_File',$diropendb,&GDBM_WRCREAT,0640)) { + my $domain = $r->dir_config('lonDefDomain'); + $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. + if (! exists($ENV{'form.persistent_db_id'}) || + ($ENV{'form.persistent_db_id'} =~ /\D/) || + ($ENV{'form.launch'} eq '1')) { + $ENV{'form.persistent_db_id'} = time; + } + $bodytag=&Apache::loncommon::bodytag(undef,undef,undef,1); + my $persistent_db_file = "/home/httpd/perl/tmp/". + &Apache::lonnet::escape($domain). + '_'.&Apache::lonnet::escape($ENV{'user.name'}). + '_'.$ENV{'form.persistent_db_id'}.'_persistent_search.db'; + ## + &Apache::lonhtmlcommon::clear_breadcrumbs(); + if (exists($ENV{'request.course.id'}) && $ENV{'request.course.id'} ne '') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/searchcat?'. + 'catalogmode='.$ENV{'form.catalogmode'}. + '&launch='.$ENV{'form.launch'}. + '&mode='.$ENV{'form.mode'}, + text=>"Course and Catalog Search", + 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", + 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 +We were unable to retrieve data describing your search. This is a serious +error and has been logged. Please alert your LON-CAPA administrator. + + +END + return OK; + } + } + } else { + &clean_up_environment(); + } + ## + ## Clear out old values from groupsearch database + ## + untie %groupsearch_db if (tied(%groupsearch_db)); + if (($ENV{'form.cleargroupsort'} eq '1') || + (($ENV{'form.launch'} eq '1') && + ($ENV{'form.catalogmode'} eq 'groupsearch'))) { + if (tie(%groupsearch_db,'GDBM_File',$diropendb,&GDBM_WRCREAT(),0640)) { &start_fresh_session(); - untie %hash; + untie %groupsearch_db; + delete($ENV{'form.cleargroupsort'}); } else { - $r->print('Unable to tie hash to db '. - 'file'); + # This is a stupid error to give to the user. + # It really tells them nothing. + $r->print(''.$bodytag. + 'Unable to tie hash to db file'); return OK; } } ## - ## Produce some output, so people know it is working + ## Configure hidden fields ## - $r->print("\n"); - $r->rflush; + $hidden_fields = ''."\n"; + if (exists($ENV{'form.catalogmode'})) { + $hidden_fields .= &hidden_field('catalogmode'); + } + if (exists($ENV{'form.form'})) { + $hidden_fields .= &hidden_field('form'); + } + if (exists($ENV{'form.element'})) { + $hidden_fields .= &hidden_field('element'); + } + if (exists($ENV{'form.titleelement'})) { + $hidden_fields .= &hidden_field('titleelement'); + } + if (exists($ENV{'form.mode'})) { + $hidden_fields .= &hidden_field('mode'); + } ## ## Configure dynamic components of interface ## - my $hidden; # Holds 'hidden' html forms if ($ENV{'form.catalogmode'} eq 'interactive') { - $hidden="". - "\n"; - $closebutton=""."\n"; + $closebutton=" -END - $closebutton=< -END + $closebutton=" END + } else { + $closebutton = ''; + $importbutton = ''; } - $hidden .= < - - - -END ## - ## What are we doing? + ## Sanity checks on form elements ## - if ($ENV{'form.basicsubmit'} eq 'SEARCH') { - # Perform basic search and give results - return &basicsearch($r,\%ENV,$hidden); - } elsif ($ENV{'form.advancedsubmit'} eq 'SEARCH') { - # Perform advanced search and give results - return &advancedsearch($r,\%ENV,$hidden); - } elsif ($ENV{'form.reqinterface'} eq 'advanced') { - # Output the advanced interface - $r->print(&advanced_search_form($closebutton,$hidden)); - return OK; - } else { - # Output normal search interface - $r->print(&basic_search_form($closebutton,$hidden)); + if (!defined($ENV{'form.viewselect'})) { + if (($ENV{'form.catalogmode'} eq 'groupsearch') || + ($ENV{'form.catalogmode'} eq 'interactive')) { + $ENV{'form.viewselect'} ="Compact View"; + } else { + $ENV{'form.viewselect'} ="Detailed Citation View"; + } + } + $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,$hidden_fields); + } elsif ($ENV{'form.phase'} eq 'disp_adv') { + &print_advanced_search_form($r,$closebutton,$hidden_fields); + } elsif ($ENV{'form.phase'} eq 'results') { + &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, + ['query','customquery','customshow', + 'libraries','pretty_string']); + if ($ENV{'form.phase'} eq 'sort') { + &print_sort_form($r,$pretty_string); + } elsif ($ENV{'form.phase'} eq 'run_search') { + &run_search($r,$query,$customquery,$customshow, + $libraries,$pretty_string); + } + } elsif ($ENV{'form.phase'} eq 'course_search') { + &course_search($r); + } elsif(($ENV{'form.phase'} eq 'basic_search') || + ($ENV{'form.phase'} eq 'adv_search')) { + # 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 +Unable to create table in which to store search results. +The search has been aborted. + + +END + return OK; + } + delete($ENV{'form.launch'}); + if (! &make_form_data_persistent($r,$persistent_db_file)) { + $r->print(<Search Error +$bodytag +Unable to properly store search information. The search has been aborted. + + +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,$libraries) = + &parse_basic_search($r,$closebutton,$hidden_fields); + } 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); + ## + ## Print out the frames interface + ## + &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; + my $bodytag=&Apache::loncommon::bodytag('Course Search'); + my $pretty_search_string = ''.$ENV{'form.courseexp'}.''; + my $search_string = $ENV{'form.courseexp'}; + my @New_Words; + if ($ENV{'form.crsrelated'}) { + ($search_string,@New_Words) = &related_version($ENV{'form.courseexp'}); + if (@New_Words) { + $pretty_search_string .= ' '.&mt("with related words").": @New_Words."; + } else { + $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.'

'); + $r->rflush(); +# ======================================================= Go through the course + undef %alreadyseen; + %alreadyseen=(); + my $c=$r->connection; + 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('

'.&mt('No resources found').'.

'); + } +# =================================================== Done going through course + $r->print(''); +} -=pod - -=item &basic_search_form() +# =============================== This pulls up a resource and its dependencies -Returns a scalar which holds html for the basic search form. +sub checkonthis { + my ($r,$url,$level,$title,$fulltext,@allwords)=@_; + $alreadyseen{$url}=1; + $r->rflush(); + my $result=&Apache::lonnet::metadata($url,'title').' '. + &Apache::lonnet::metadata($url,'subject').' '. + &Apache::lonnet::metadata($url,'abstract').' '. + &Apache::lonnet::metadata($url,'keywords'); + if (($url) && ($fulltext)) { + $result.=&Apache::lonnet::ssi_body($url); + } + $result=~s/\s+/ /gs; + my $applies=0; + foreach (@allwords) { + if ($_=~/\w/) { + if ($result=~/$_/si) { + $applies++; + } + } + } +# Does this resource apply? + if ($applies) { + $r->print('
'); + for (my $i=0;$i<=$level*5;$i++) { + $r->print(' '); + } + $r->print(''. + ($title?$title:$url).'
'); + $totalfound++; + } elsif ($fulltext) { + $r->print(' .'); + } + $r->rflush(); +# Check also the dependencies of this one + my $dependencies= + &Apache::lonnet::metadata($url,'dependencies'); + foreach (split(/\,/,$dependencies)) { + if (($_=~/^\/res\//) && (!$alreadyseen{$_})) { + &checkonthis($r,$_,$level+1,'',$fulltext,@allwords); + } + } +} -=cut +sub untiehash { + if (tied(%hash)) { + untie(%hash); + } +} -###################################################################### -###################################################################### +} # End of course search scoping -sub basic_search_form{ - my ($closebutton,$hidden) = @_; - my $scrout=<<"ENDDOCUMENT"; +sub search_html_header { + my $Str = < The LearningOnline Network with CAPA - - - -

Search Catalog

-
-$hidden -

Basic Search

+ENDHEADER + return $Str; +} + +###################################################################### +###################################################################### + +=pod + +=item &print_basic_search_form() + +Prints the form for the basic search. Sorry the name is so cryptic. + +=cut + +###################################################################### +###################################################################### +sub print_basic_search_form { + my ($r,$closebutton,$hidden_fields) = @_; + my $bodytag=&Apache::loncommon::bodytag('Search'). + &Apache::lonhtmlcommon::breadcrumbs(undef,'Searching','Searching', + undef,undef,! $ENV{'form.launch'}); + my $scrout = &search_html_header().$bodytag; + if (&Apache::lonnet::allowed('bre',$ENV{'request.role.domain'})) { + # Define interface components + my $userelatedwords= + &mt('[_1] use related words', + &Apache::lonhtmlcommon::checkbox + ('related',$ENV{'form.related'},'related')); + my $onlysearchdomain= + &mt('[_1] only search domain [_2]', + &Apache::lonhtmlcommon::checkbox('domains', + $ENV{'form.domains'}, + $r->dir_config('lonDefDomain') + ), + $r->dir_config('lonDefDomain') + ); + my $adv_search_link = + ''.&mt('Advanced Search').''; + # + $scrout.=''. + ''. + $hidden_fields; + # + $scrout .= '
'.$/; + if ($ENV{'request.course.id'}) { + $scrout .= '

'.&mt('LON-CAPA Catalog Search').'

'; + } else { + # No need to tell them they are searching + $scrout.= ('
'x2); + } + $scrout.=''. + ''. + ''. + ''.$/; + # +# $scrout .= ''.$/; + $scrout .= ''.$/; + $scrout .= '
'. + &Apache::lonhtmlcommon::textbox('basicexp', + $ENV{'form.basicexp'},50).'
'. + ''.&searchhelp().''.'
'. + ''.(' 'x3).$adv_search_link.''.'
'. + ''.(' 'x1).$userelatedwords.''.'
'. + ''.(' 'x1).$onlysearchdomain.''.'
'. + '
'. +# ''. +# $userelatedwords.(' 'x3). +# $onlysearchdomain.(' 'x2).$adv_search_link. +# ''. +# '
'. + ''. + ''. + (' 'x2).$closebutton.(' 'x2). + &viewoptions(). + ''. + '
'.$/.'
'.'
'; + } + if ($ENV{'request.course.id'}) { + my %lt=&Apache::lonlocal::texthash('srch' => 'Search', + 'header' => 'Course Search', + 'note' => 'Enter terms or phrases, then press "Search" below', + 'use' => 'use related words', + 'full' =>'fulltext search (time consuming)' + ); + $scrout.=(< +
+
+

$lt{'header'}

+ +$hidden_fields

-Enter terms or quoted phrases separated by AND, OR, or NOT -then press SEARCH below. +$lt{'note'}.

-ENDDOCUMENT - $scrout.=' '.&simpletextfield('basicexp',$ENV{'form.basicexp'},40). - ' '; -# $scrout.=&simplecheckbox('allversions',$ENV{'form.allversions'}); -# $scrout.='Search historic archives'; - $scrout.=<Advanced Search
-

-

  -$closebutton - - - - +ENDCOURSESEARCH + $scrout.=' '. + &Apache::lonhtmlcommon::textbox('courseexp', + $ENV{'form.courseexp'},40); + my $crscheckbox = + &Apache::lonhtmlcommon::checkbox('crsfulltext', + $ENV{'form.crsfulltext'}); + my $relcheckbox = + &Apache::lonhtmlcommon::checkbox('crsrelated', + $ENV{'form.crsrelated'}); + $scrout.=(< +$relcheckbox $lt{'use'} +$crscheckbox $lt{'full'} +

+
+ENDENDCOURSE + } + $scrout.=(< ENDDOCUMENT - return $scrout; + $r->print($scrout); + return; } ###################################################################### ###################################################################### @@ -314,164 +680,225 @@ ENDDOCUMENT =item &advanced_search_form() -Returns a scalar which holds html for the advanced search form. +Prints the advanced search form. =cut ###################################################################### ###################################################################### +sub print_advanced_search_form{ + my ($r,$closebutton,$hidden_fields) = @_; + my $bodytag=&Apache::loncommon::bodytag('Advanced Catalog Search'). + &Apache::lonhtmlcommon::breadcrumbs(undef,'Searching', + 'Searching', + undef,undef, + ! $ENV{'form.launch'}); -sub advanced_search_form{ - my ($closebutton,$hidden) = @_; - my $advanced_buttons = <<"END"; -

- - + my %lt=&Apache::lonlocal::texthash('srch' => 'Search', + 'reset' => 'Reset', + 'help' => 'Help'); + my $advanced_buttons=<<"END"; + + $closebutton - - - - -

END - my $scrout=<<"ENDHEADER"; - - -The LearningOnline Network with CAPA - - - - -

Advanced Catalog Search

-
-Enter terms or quoted phrases separated by search operators -such as AND, OR, or NOT.
+ my $scrout=&search_html_header(); + $scrout .= <<"ENDHEADER"; +$bodytag +
+

$advanced_buttons -$hidden - ENDHEADER - $scrout.=&searchphrasefield('title','title', - $ENV{'form.title'}); - $scrout.=&searchphrasefield('author','author', - $ENV{'form.author'}); - $scrout.=&searchphrasefield('subject','subject', - $ENV{'form.subject'}); - $scrout.=&searchphrasefield('keywords','keywords', - $ENV{'form.keywords'}); - $scrout.=&searchphrasefield('URL','url', - $ENV{'form.url'}); -# $scrout.=&searchphrasefield('Limit by version','version', -# $ENV{'form.version'}); - $scrout.=&searchphrasefield('notes','notes', - $ENV{'form.notes'}); - $scrout.=&searchphrasefield('abstract','abstract', - $ENV{'form.abstract'}); - # Hack - an empty table row. - $scrout.="\n"; - $scrout.=&searchphrasefield('file
extension','mime', - $ENV{'form.mime'}); - $scrout.="\n"; - $scrout.=&searchphrasefield('publisher
owner','owner', - $ENV{'form.owner'}); + $scrout.=(' 'x2).&viewoptions().'

'.$hidden_fields. + ''; + my %fields=&Apache::lonmeta::fieldnames(); + # + $scrout .= '

'.&mt('Standard Metadata').'

'; + $scrout .= "
  
  
\n"; + $scrout .= '\n"; + my %related_word_search = + ('title' => 1, + 'author' => 0, + 'owner' => 0, + 'authorspace' => 0, + 'modifyinguser'=> 0, + 'keywords' => 1, + 'notes' => 1, + 'abstract' => 1, + 'standards'=> 1, + 'mime' => 1, + ); + # + foreach my $field ('title','author','owner','authorspace','modifyinguser', + 'keywords','notes','abstract','standards','mime') { + $scrout.=''.$/; + } + foreach my $field ('lowestgradelevel','highestgradelevel') { + $scrout.=''. + ''. + ''.$/; + } + $scrout.=''.$/; + $scrout.=''.$/; + # + # Misc metadata + $scrout.=''.$/; + $scrout.=''; + $scrout .= "
 '. + (' 'x2).&searchhelp()."
'.&titlefield($fields{$field}).''. + &Apache::lonmeta::prettyinput($field, + $ENV{'form.'.$field}, + $field, + 'advsearch', + $related_word_search{$field}, + '', + $ENV{'form.'.$field.'_related'}, + 50); + if ($related_word_search{$field}) { + $scrout .= 'related words'; + } else { + $scrout .= ' '; + } + $scrout .= '
'.&titlefield($fields{$field}).''. + &Apache::lonmeta::prettyinput($field, + $ENV{'form.'.$field}, + $field, + 'advsearch', + 0). + '
'. + &titlefield(&mt('MIME Type Category')).''. + &Apache::loncommon::filecategoryselect('category', + $ENV{'form.category'}). + '
'. + &titlefield(&mt('Domains')).''. + &Apache::loncommon::domain_select('domains', + $ENV{'form.domains'},1). + '
'. + &titlefield(&mt('Copyright/Distribution')).''. + &Apache::lonmeta::selectbox('copyright', + '',, + \&Apache::loncommon::copyrightdescription, + ( undef, + &Apache::loncommon::copyrightids) + ).'
'. + &titlefield(&mt('Language')).''. + &Apache::lonmeta::selectbox('language', + 'notset',, + \&Apache::loncommon::languagedescription, + ('any',&Apache::loncommon::languageids) + ).'
\n"; + # + # Dynamic metadata + $scrout .= '

'.&mt('Problem Statistics').'

'; + $scrout .= "\n"; + $scrout .= ''. + ''."\n"; + foreach my $statistic + ({ name=>'count', + description=>'Network-wide number of accesses (hits)',}, + { name=>'stdno', + description=> + 'Total number of students who have worked on this problem',}, + { name => 'avetries', + description=>'Average number of tries till solved',}, + { name => 'difficulty', + description=>'Degree of difficulty',}, + { name => 'disc', + description=>'Degree of discrimination'}) { + $scrout .= ''.$/; + } + $scrout .= "
 '.&mt('Minimum').''.&mt('Maximum').'
'. + &titlefield(&mt($statistic->{'description'})). + ''. + ''. + ''. + ''. + '
\n"; + $scrout .= '

'.&mt('Evaluation Data').'

'; + $scrout .= "\n"; + $scrout .= ''. + ''."\n"; + foreach my $evaluation + ( { name => 'clear', + description => 'Material presented in clear way'}, + { name =>'depth', + description => 'Material covered with sufficient depth'}, + { name => 'helpful', + description => 'Material is helpful'}, + { name => 'correct', + description => 'Material appears to be correct'}, + { name => 'technical', + description => 'Resource is technically correct'}){ + $scrout .= ''.$/; + } + $scrout .= "
 '.&mt('Minimum').''.&mt('Maximum').'
'. + &titlefield(&mt($evaluation->{'description'})). + ''. + ''. + ''. + ''. + '
\n"; + # + # Creation/Modification date limits + $scrout .= '

'.&mt('Creation and Modification dates').'

'; + $scrout .= "\n\n"; + my $cafter = + &Apache::lonhtmlcommon::date_setter('advsearch', # formname + 'creationdate1', # fieldname + 0, # current value + '', # special + 1, # includeempty + '', # state + 1, # no_hh_mm_ss + ); + my $cbefore = + &Apache::lonhtmlcommon::date_setter('advsearch', # formname + 'creationdate2', # fieldname + 0, # current value + '', # special + 1, # includeempty + '', # state + 1, # no_hh_mm_ss + ); + $scrout .= &mt(''. + ''. + ''. + '',$cafter,$cbefore); + my $lafter = + &Apache::lonhtmlcommon::date_setter('advsearch', + 'revisiondate1', + 0, # current value + '', # special + 1, # includeempty + '', # state + 1, # no_hh_mm_ss + ); + my $lbefore = + &Apache::lonhtmlcommon::date_setter('advsearch', + 'revisiondate2', + 0, # current value + '', # special + 1, # includeempty + '', # state + 1, # no_hh_mm_ss + ); + $scrout .= &mt(''. + ''. + ''. + '',$lafter,$lbefore); $scrout.="
Created between[_1]
and [_2]
Last modified between [_1]
and[_2]
\n"; -# $ENV{'form.mime'}='any' unless length($ENV{'form.mime'}); -# $scrout.=&selectbox('Limit by MIME type','mime', -# $ENV{'form.mime'}, -# 'any','Any type', -# \&{Apache::loncommon::filedescriptionex}, -# (&Apache::loncommon::fileextensions)); - $ENV{'form.language'}='any' unless length($ENV{'form.language'}); - $scrout.=&selectbox('Limit by language','language', - $ENV{'form.language'},'any','Any Language', - \&{Apache::loncommon::languagedescription}, - (&Apache::loncommon::languageids), - ); -# ------------------------------------------------ Compute date selection boxes - $scrout.=< -LIMIT BY CREATION DATE RANGE: - -
-between: -CREATIONDATESTART - $scrout.=&dateboxes('creationdatestart',1,1,1976, - $ENV{'form.creationdatestart_month'}, - $ENV{'form.creationdatestart_day'}, - $ENV{'form.creationdatestart_year'}, - ); - $scrout.="and:\n"; - $scrout.=&dateboxes('creationdateend',12,31,2051, - $ENV{'form.creationdateend_month'}, - $ENV{'form.creationdateend_day'}, - $ENV{'form.creationdateend_year'}, - ); - $scrout.="

"; - $scrout.=< -LIMIT BY LAST REVISION DATE RANGE: - -
between: -LASTREVISIONDATESTART - $scrout.=&dateboxes('lastrevisiondatestart',1,1,1976, - $ENV{'form.lastrevisiondatestart_month'}, - $ENV{'form.lastrevisiondatestart_day'}, - $ENV{'form.lastrevisiondatestart_year'}, - ); - $scrout.=< -LIMIT BY SPECIAL METADATA FIELDS: - -For resource-specific metadata, enter in an expression in the form of -key=value separated by operators such as AND, OR or NOT.
-Example: grandmother=75 OR grandfather=85 -
-CUSTOMMETADATA - $scrout.=&simpletextfield('custommetadata',$ENV{'form.custommetadata'}); - $scrout.=< -SHOW SPECIAL METADATA FIELDS: - -Enter in a space-separated list of special metadata fields to show -in a fielded listing for each record result. -
-CUSTOMSHOW - $scrout.=&simpletextfield('customshow',$ENV{'form.customshow'}); $scrout.=< ENDDOCUMENT - return $scrout; + $r->print($scrout); + return; } ###################################################################### @@ -479,204 +906,258 @@ ENDDOCUMENT =pod -=item &make_persistent() +=item &titlefield() -Returns a scalar which holds the current ENV{'form.*'} values in -a 'hidden' html input tag. This allows search interface information -to be somewhat persistent. +Inputs: title text + +Outputs: titletext with font wrapper =cut ###################################################################### ###################################################################### - -sub make_persistent { - my $persistent=''; - foreach (keys %ENV) { - if (/^form\./ && !/submit/) { - my $name=$_; - my $key=$name; - $ENV{$key}=~s/\'//g; # do not mess with html field syntax - $name=~s/^form\.//; - $persistent.=< -END - } - } - return $persistent; +sub titlefield { + my $title=shift; + return $title; } - ###################################################################### ###################################################################### =pod -=item HTML form building functions +=item viewoptiontext() -=over 4 +Inputs: codename for view option -=item &simpletextfield() +Outputs: displayed text -Inputs: $name,$value,$size +=cut -Returns a text input field with the given name, value, and size. -If size is not specified, a value of 20 is used. +###################################################################### +###################################################################### +sub viewoptiontext { + my $code=shift; + my %desc=&Apache::lonlocal::texthash + ('detailed' => "Detailed Citation View", + 'xml' => 'XML/SGML', + 'compact' => 'Compact View', + 'fielded' => 'Fielded Format', + 'summary' => 'Summary View'); + return $desc{$code}; +} -=item &simplecheckbox() +###################################################################### +###################################################################### -Inputs: $name,$value +=pod -Returns a simple check box with the given $name. -If $value eq 'on' the box is checked. +=item viewoptions() -=item &searchphrasefield() +Inputs: none -Inputs: $title,$name,$value +Outputs: text for box with view options -Returns html for a title line and an input field for entering search terms. -the instructions "Enter terms or phrases separated by search operators such -as AND, OR, or NOT." are given following the title. The entry field (which -is where the $name and $value are used) is an 80 column simpletextfield. +=cut -=item &dateboxes() +###################################################################### +###################################################################### +sub viewoptions { + my $scrout; + if (! defined($ENV{'form.viewselect'})) { + $ENV{'form.viewselect'}='detailed'; + } + $scrout.=&Apache::lonmeta::selectbox('viewselect', + $ENV{'form.viewselect'}, + \&viewoptiontext, + sort(keys(%Views))); + $scrout.= '  '; + my $countselect = &Apache::lonmeta::selectbox('show', + $ENV{'form.show'}, + undef, + (10,20,50,100,1000,10000)); + $scrout .= (' 'x2).&mt('[_1] Records per Page',$countselect). + ''.$/; + return $scrout; +} -Returns html selection form elements for the specification of -the day, month, and year. +###################################################################### +###################################################################### -=item &selectbox() +=pod -Returns a scalar containing an html tag. +=pod -=item $default +=item &get_persistent_form_data() -The default value of the form. Can be $anyvalue or in @idlist. +Inputs: filename of database -=item $anyvalue +Outputs: returns undef on database errors. -The