--- loncom/interface/lonsearchcat.pm 2002/07/26 16:37:58 1.144 +++ loncom/interface/lonsearchcat.pm 2013/09/01 22:39:39 1.336 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Search Catalog # -# $Id: lonsearchcat.pm,v 1.144 2002/07/26 16:37:58 matthew Exp $ +# $Id: lonsearchcat.pm,v 1.336 2013/09/01 22:39:39 raeburn 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 -# ############################################################################### ############################################################################### @@ -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,293 +59,488 @@ 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::lonnet(); +use Apache::Constants qw(:common :http); +use Apache::lonnet; use Apache::File(); use CGI qw(:standard); use Text::Query; -use DBI; use GDBM_File; use Apache::loncommon(); use Apache::lonmysql(); - -# ---------------------------------------- variables used throughout the module +use Apache::lonmeta; +use Apache::lonhtmlcommon; +use Apache::lonlocal; +use LONCAPA::lonmetadata(); +use HTML::Entities(); +use Parse::RecDescent; +use Apache::lonnavmaps; +use Apache::lonindexer(); +use Apache::lonwishlist(); +use LONCAPA; ###################################################################### ###################################################################### - -=pod - -=item Global variables - -=over 4 - -=item $closebutton - -button that closes the search window - -=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 $results_db - -The name of the database results from searches are put in. - -=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 %groupsearch_db; # database hash -my $diropendb = ""; # db file - -my $results_db = ""; -# 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 ); - +## +## Global variables +## ###################################################################### ###################################################################### - -=pod - -=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 %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 + +# The different view modes and associated functions + +my %Views = ("detailed" => \&detailed_citation_view, + "detailedpreview" => \&detailed_citation_preview, + "summary" => \&summary_view, + "summarypreview" => \&summary_preview, + "fielded" => \&fielded_format_view, + "xml" => \&xml_sgml_view, + "compact" => \&compact_view); ###################################################################### ###################################################################### sub handler { my $r = shift; - untie %groupsearch_db; +# &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(). - $r->content_type('text/html'); + # + 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; ## + ## 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','pause', + 'phase','persistent_db_id','table','start','show', + 'cleargroupsort','titleelement','area','inhibitmenu']); + ## + ## 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'}); + } + ## ## 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"; - $results_db = "/home/httpd/perl/tmp/".&Apache::lonnet::escape($domain). - '_'.&Apache::lonnet::escape($ENV{'user.name'})."_searchresults.db"; - &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['catalogmode','launch','acts','mode','form','element', - 'reqinterface']); + my $temp_file_dir = LONCAPA::tempdir(); + $diropendb= $temp_file_dir . + "$env{'user.domain'}_$env{'user.name'}_sel_res.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; + } + + my $persistent_db_file = $temp_file_dir . + &escape($domain). + '_'.&escape($env{'user.name'}). + '_'.$env{'form.persistent_db_id'}.'_persistent_search.db'; + ## + &Apache::lonhtmlcommon::clear_breadcrumbs(); + + my @allowed_searches = ('portfolio'); + if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'})) { + push(@allowed_searches,'res'); + } + my $crumb_text = 'Portfolio Search'; + if (@allowed_searches ==2) { + $crumb_text = 'Portfolio and Catalog Search'; + } + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/searchcat?'. + &Apache::loncommon::inhibit_menu_check(). + '&catalogmode='.$env{'form.catalogmode'}. + '&launch='.$env{'form.launch'}. + '&mode='.$env{'form.mode'}, + text=>"$crumb_text", + 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); + my $msg = + 'We were unable to retrieve data describing your search. '. + 'This is a serious error and has been logged. '. + 'Please alert your LON-CAPA administrator.'; + &Apache::loncommon::simple_error_page($r,'Search Error', + $msg); + return OK; + } + } + } else { + &clean_up_environment(); + } ## ## Clear out old values from groupsearch database ## - if ($ENV{'form.launch'} eq '1') { - if (tie(%groupsearch_db,'GDBM_File',$diropendb,&GDBM_WRCREAT,0640)) { + untie %groupsearch_db if (tied(%groupsearch_db)); + if (($env{'form.cleargroupsort'} eq '1') || + (($env{'form.launch'} eq '1') && + ($env{'form.catalogmode'} eq 'import'))) { + if (tie(%groupsearch_db,'GDBM_File',$diropendb,&GDBM_WRCREAT(),0640)) { &start_fresh_session(); 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. + my $msg = 'Unable to tie hash to db file.'; + &Apache::loncommon::simple_error_page($r,'Search Error', + $msg); 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'); + } + if (exists($env{'form.area'})) { + $hidden_fields .= &hidden_field('area'); + } + if (exists($env{'form.inhibitmenu'})) { + $hidden_fields .= &hidden_field('inhibitmenu'); + } ## ## Configure dynamic components of interface ## - my $hidden; # Holds 'hidden' html forms - if ($ENV{'form.catalogmode'} eq 'interactive') { - $hidden="". - "\n"; - $closebutton=""."\n"; - } elsif ($ENV{'form.catalogmode'} eq 'groupsearch') { - $hidden=< -END - $closebutton=< -END + if ($env{'form.catalogmode'} eq 'interactive') { + $closebutton=" + END + } else { + $closebutton = ''; + $importbutton = ''; + } + ## + ## Sanity checks on form elements + ## + if (!defined($env{'form.viewselect'})) { + $env{'form.viewselect'} ="summary"; + } + $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'; } - $hidden .= &make_persistent({ "form.mode" => $ENV{'form.mode'}, - "form.form" => $ENV{'form.form'}, - "form.element" => $ENV{'form.element'}, - "form.date" => 2 }); - ## - ## What are we doing? - ## - my $searchtype; - $searchtype = 'Basic' if ($ENV{'form.basicsubmit'} eq 'SEARCH'); - $searchtype = 'Advanced' if ($ENV{'form.advancedsubmit'} eq 'SEARCH'); - if ($searchtype) { - # We are running a search - my ($query,$customquery,$customshow,$libraries) = - (undef,undef,undef,undef); + # + if ($env{'form.searchmode'} eq 'advanced') { + my $srchtype = 'Catalog'; + if ($env{'form.area'} eq 'portfolio') { + $srchtype = 'Portfolio'; + } + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/searchcat?'.&Apache::loncommon::inhibit_menu_check(). + '&phase=disp_adv'. + '&catalogmode='.$env{'form.catalogmode'}. + '&launch='.$env{'form.launch'}. + '&mode='.$env{'form.mode'}, + text=>"Advanced $srchtype 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, + $env{'form.area'}); + } elsif ($env{'form.phase'} =~ /^(sort|run_search)$/) { + my ($query,$customquery,$customshow,$libraries,$pretty_string,$domainsref) = + &get_persistent_data($persistent_db_file, + ['query','customquery','customshow', + 'libraries','pretty_string','domains']); + 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,$env{'form.area'},$domainsref); + } + } elsif(($env{'form.phase'} eq 'basic_search') || + ($env{'form.phase'} eq 'adv_search')) { + # + # We are running a search, try to parse it + my ($query,$customquery,$customshow,$libraries,$domains) = + (undef,undef,undef,undef,undef); my $pretty_string; - if ($searchtype eq 'Basic') { - ($query,$pretty_string) = &parse_basic_search($r); - } elsif ($ENV{'form.advancedsubmit'} eq 'SEARCH') { - ($query,$customquery,$customshow,$libraries,$pretty_string) - = &parse_advanced_search($r); + if ($env{'form.phase'} eq 'basic_search') { + ($query,$pretty_string,$libraries,$domains) = + &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,$domains) + = &parse_advanced_search($r,$closebutton,$hidden_fields); return OK if (! defined($query)); } - # Output some information to the user. - $r->print(&search_results_header($searchtype,$pretty_string)); - $r->print("Sending search request to LON-CAPA servers.
\n"); - $r->rflush(); - &run_search($r,$query,$customquery,$customshow,$libraries); - &display_results($r,$searchtype,$hidden,$importbutton, - $closebutton); - - $r->rflush(); - } else { + &make_persistent({ query => $query, + customquery => $customquery, + customshow => $customshow, + libraries => $libraries, + pretty_string => $pretty_string, + domains => $domains }, + $persistent_db_file); # - # We need to get information to search on - # - # Set the default view if it is not already set. - if (!defined($ENV{'form.viewselect'})) { - $ENV{'form.viewselect'} ="Detailed Citation View"; - } - # Output the advanced interface - if ($ENV{'form.reqinterface'} eq 'advanced') { - $r->print(&advanced_search_form($closebutton,$hidden)); - } else { - # Output normal search interface - $r->print(&basic_search_form($closebutton,$hidden)); + # Set up table + if (! defined(&create_results_table($env{'form.area'}))) { + my $errorstring=&Apache::lonmysql::get_error(); + &Apache::lonnet::logthis('lonsearchcat.pm: Unable to create '. + 'needed table. lonmysql error:'. + $errorstring); + + my $msg = + 'Unable to create table in which to save search results. '. + 'The search has been aborted.'; + &Apache::loncommon::simple_error_page($r,'Search Error', + $msg); + return OK; + } + delete($env{'form.launch'}); + if (! &make_form_data_persistent($r,$persistent_db_file)) { + my $msg= + 'Unable to properly save search information. '. + 'The search has been aborted.'; + &Apache::loncommon::simple_error_page($r,'Search Error', + $msg); + return OK; + } + ## + ## Print out the frames interface + ## + 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 ''.$/; +} + ###################################################################### =pod -=item &basic_search_form() +=item &print_basic_search_form() -Returns a scalar which holds html for the basic search form. +Prints the form for the basic search. Sorry the name is so cryptic. =cut ###################################################################### ###################################################################### - -sub basic_search_form{ - my ($closebutton,$hidden) = @_; - my $scrout=<<"ENDDOCUMENT"; - - -The LearningOnline Network with CAPA - - - - -

Search Catalog

-
-$hidden -

Basic Search

-

-Enter terms or phrases separated by AND, OR, or NOT -then press SEARCH below. -

-

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

-

  -$closebutton -END - $scrout.=&selectbox(undef,'viewselect', - $ENV{'form.viewselect'}, - undef,undef,undef, - sort(keys(%Views))); - $scrout.=< -

-
- - -ENDDOCUMENT - return $scrout; +# Search form for accessible portfolio files + $scrout.= &setup_basic_search($r,'portfolio',$hidden_fields,$closebutton); + $scrout .= &Apache::loncommon::end_page(); + $r->print($scrout); + return; } + +sub setup_basic_search { + my ($r,$area,$hidden_fields,$closebutton) = @_; + # Define interface components + my %lt = &Apache::lonlocal::texthash ( + res => 'LON-CAPA Catalog Search', + portfolio => 'Portfolio Search', + ); + my ($userelatedwords,$onlysearchdomain,$inclext,$adv_search_link,$scrout); + + $userelatedwords = ''; + + $onlysearchdomain = ''; + + $adv_search_link = ''.&mt('Advanced Search').''; + # + $scrout.='
'. + ''. + $hidden_fields; + if (!exists($env{'form.area'})) { + $scrout .= ''; + } + # + $scrout .= '
'.$/; +# if ($env{'request.course.id'}) { + $scrout .= '

'.$lt{$area}.'

'; +# } else { + # No need to tell them they are searching +# $scrout.= ('
'x2); +# } + $scrout.=''. + ''. + ''. + ''. + '
'. + &Apache::lonhtmlcommon::textbox('basicexp', + $env{'form.basicexp'},50). + '
'. + ''.&searchhelp().''.'
'. + ''.(' 'x3).$adv_search_link.''.'
'. + ''.(' 'x1).$userelatedwords.''.'
'. + ''.(' 'x1).$onlysearchdomain.''.'
'. + ''.(' 'x1).$inclext.''.'
'. + '
'.$/; + # + $scrout .= '

' + .&viewoptions() + .'

' + .'

' + .'' + .' ' + .$closebutton + .'

'; + # + $scrout .= '
'.'
'; + return $scrout; +} + ###################################################################### ###################################################################### @@ -361,194 +548,297 @@ ENDDOCUMENT =item &advanced_search_form() -Returns a scalar which holds html for the advanced search form. +Prints the advanced search form. =cut ###################################################################### ###################################################################### - -sub advanced_search_form{ - my ($closebutton,$hidden) = @_; - my $advanced_buttons = <<"END"; +sub print_advanced_search_form{ + my ($r,$closebutton,$hidden_fields) = @_; + my $bread_crumb = + &Apache::lonhtmlcommon::breadcrumbs('Searching','Search_Advanced', + $env{'form.catalogmode'} ne 'import'); + my %lt=&Apache::lonlocal::texthash('srch' => 'Search', + 'reset' => 'Reset', + 'help' => 'Help'); + my $advanced_buttons=<<"END";

- - + + $closebutton -

END - if (!defined($ENV{'form.viewselect'})) { - $ENV{'form.viewselect'} ="Detailed Citation View"; - } - my $scrout=<<"ENDHEADER"; - - -The LearningOnline Network with CAPA -'; + } + my $scrout= &Apache::loncommon::start_page("Advanced $srchtype Search", + $jscript); + $scrout .= $bread_crumb; + + $scrout .= '
' + .$hidden_fields + .''; + + $scrout .= '
'."\n" + .''.&mt('Display Options').''."\n" + .&viewoptions() + .'
'; + + $scrout .= $advanced_buttons; + + $scrout .= &Apache::lonhtmlcommon::start_pick_box(); + + my %fields=&Apache::lonmeta::fieldnames(); + + # Standard Metadata + $scrout .= &Apache::lonhtmlcommon::row_headline() + .'

'.&mt("Standard $srchtype Metadata").'

' + .&searchhelp() + .&Apache::lonhtmlcommon::row_closure(); + my %related_word_search = + ('title' => 1, + 'author' => 0, + 'owner' => 0, + 'authorspace' => 0, + 'modifyinguser'=> 0, + 'keywords' => 1, + 'notes' => 1, + 'abstract' => 1, + 'standards'=> 1, + 'mime' => 1, + 'subject' => 1, + ); + # + foreach my $field ('title','author','subject','owner','authorspace', + 'modifyinguser','keywords','notes','abstract', + 'standards','mime') { + $scrout .= &Apache::lonhtmlcommon::row_title(&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 .= &mt('related words'); + } else { + $scrout .= ''; + } + $scrout .= &Apache::lonhtmlcommon::row_closure(); } - - - - -

Advanced Catalog Search

-
-Enter terms or phrases separated by search operators -such as AND, OR, or NOT.
- -$advanced_buttons -$hidden - - -\n"; - $scrout.=&searchphrasefield_with_related('title', 'title' , - $ENV{'form.title'}); - $scrout.=&searchphrasefield('author', 'author' ,$ENV{'form.author'}); - $scrout.=&searchphrasefield_with_related('subject', 'subject' , - $ENV{'form.subject'}); - $scrout.=&searchphrasefield_with_related('keywords','keywords', - $ENV{'form.keywords'}); - $scrout.=&searchphrasefield('URL', 'url' ,$ENV{'form.url'}); - $scrout.=&searchphrasefield_with_related('notes', 'notes' , - $ENV{'form.notes'}); - $scrout.=&searchphrasefield_with_related('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.="
VIEW: -ENDHEADER - $scrout.=&selectbox(undef,'viewselect', - $ENV{'form.viewselect'}, - undef,undef,undef, - sort(keys(%Views))); - $scrout.="Related
Words
   
   
\n"; - $ENV{'form.category'}='any' unless length($ENV{'form.category'}); - $scrout.=&selectbox('File Category','category', - $ENV{'form.category'}, - 'any','Any category', - undef, - (&Apache::loncommon::filecategories())); - $ENV{'form.language'}='any' unless length($ENV{'form.language'}); - #---------------------------------------------------------------- - # Allow restriction to multiple domains. - # I make the crazy assumption that there will never be a domain 'any'. - # - $ENV{'form.domains'} = 'any' if (! exists($ENV{'form.domains'})); - my @allowed_domains = (ref($ENV{'form.domains'}) ? @{$ENV{'form.domains'}} - : ($ENV{'form.domains'}) ); - my %domain_hash = (); - foreach (@allowed_domains) { - $domain_hash{$_}++; + foreach my $field ('lowestgradelevel','highestgradelevel') { + $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield($fields{$field})) + .&Apache::lonmeta::prettyinput($field, + $env{'form.'.$field}, + $field, + 'advsearch', + 0) + .&Apache::lonhtmlcommon::row_closure(); + } + + $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt('MIME Type Category'))) + .&Apache::loncommon::filecategoryselect('category', + $env{'form.category'}) + .&Apache::lonhtmlcommon::row_closure(); + + $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt('Domains'))) + .&Apache::loncommon::domain_select('domains', + $env{'form.domains'},1) + .&Apache::lonhtmlcommon::row_closure(); + + # Misc metadata + if ($env{'form.area'} ne 'portfolio') { + $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt('Copyright/Distribution'))) + .&Apache::lonmeta::selectbox('copyright', + $env{'form.copyright'}, + \&Apache::loncommon::copyrightdescription, + ( undef, + &Apache::loncommon::copyrightids) + ) + .&Apache::lonhtmlcommon::row_closure(); + } + + $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt('Language'))) + .&Apache::lonmeta::selectbox('language', + $env{'form.language'}, + \&Apache::loncommon::languagedescription, + ('any',&Apache::loncommon::languageids) + ) + .&Apache::lonhtmlcommon::row_closure(); + + # Portfolio Metadata + if ($env{'form.area'} eq 'portfolio') { + # Added fields + my $curnumadd = $env{'form.numaddedfields'}; + if ($curnumadd eq '') { + $curnumadd = 1; + } + $scrout .= &Apache::lonhtmlcommon::row_headline() + .'

'.&mt('Custom Metadata fields').'

' + .&Apache::lonhtmlcommon::row_closure() + .&Apache::lonhtmlcommon::row_title('') + .&mt('Field Name').' | '.&mt('Field Value(s)') + .&Apache::lonhtmlcommon::row_closure(); + + for (my $j=0; $j<$curnumadd; $j++) { + my $num = $j+1; + $scrout .= &Apache::lonhtmlcommon::row_title(&mt('Custom metadata [_1]',$num)) + .'' + .' ' + .'' + .&Apache::lonhtmlcommon::row_closure(); + } + $scrout .= &Apache::lonhtmlcommon::row_title('') + .'' + .'' + .&Apache::lonhtmlcommon::row_closure(); +} else { + # + # Dynamic metadata + $scrout .= &Apache::lonhtmlcommon::row_headline() + .'

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

' + .&Apache::lonhtmlcommon::row_closure(); + $scrout .= &Apache::lonhtmlcommon::row_title('') + .&mt('Minimum').' | '.&mt('Maximum') + .&Apache::lonhtmlcommon::row_closure(); + foreach my $statistic + ({ name=>'count', + description=>'Network-wide number of accesses (hits)',}, + { name=>'stdno', + description=> + 'Statistics calculated for number of students',}, + { name => 'avetries', + description=>'Average number of tries till solved',}, + { name => 'difficulty', + description=>'Degree of difficulty',}, + { name => 'disc', + description=>'Degree of discrimination'}) { + $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt($statistic->{'description'}))) + .'' + .' ' + .'' + .&Apache::lonhtmlcommon::row_closure(); + } + + $scrout .= &Apache::lonhtmlcommon::row_headline() + .'

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

' + .&Apache::lonhtmlcommon::row_closure(); + $scrout .= &Apache::lonhtmlcommon::row_title('') + .&mt('Minimum').' | '.&mt('Maximum') + .&Apache::lonhtmlcommon::row_closure(); + 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 .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt($evaluation->{'description'}))) + .'' + .' ' + .'' + .&Apache::lonhtmlcommon::row_closure(); + } } - my @domains =&Apache::loncommon::get_domains(); - # adjust the size of the select box - my $size = 4; - my $size = (scalar @domains < ($size - 1) ? scalar @domains + 1 : $size); - # standalone machines do not get to choose a domain to search. - if ((scalar @domains) == 1) { - $scrout .=''."\n"; - } else { - $scrout.="\n".''. - 'DOMAINS
'. - '\n"; - } - #---------------------------------------------------------------- - $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; + # + # Creation/Modification date limits + $scrout .= &Apache::lonhtmlcommon::row_headline() + .'

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

' + .&Apache::lonhtmlcommon::row_closure(); + $scrout .= &Apache::lonhtmlcommon::row_title('') + .&mt('Month[_1]Day[_2]Year',' 'x14,' 'x6) + .&Apache::lonhtmlcommon::row_closure(); + + 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 .= &Apache::lonhtmlcommon::row_title(&mt('Created between')) + .$cafter + .&Apache::lonhtmlcommon::row_closure(1) + .&Apache::lonhtmlcommon::row_title(&mt('and')) + .$cbefore + .&Apache::lonhtmlcommon::row_closure(); + + 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 .= &Apache::lonhtmlcommon::row_title(&mt('Last modified between')) + .$lafter + .&Apache::lonhtmlcommon::row_closure(1) + .&Apache::lonhtmlcommon::row_title(&mt('and')) + .$lbefore + .&Apache::lonhtmlcommon::row_closure(1); # Last row of total pick_box + + $scrout .= &Apache::lonhtmlcommon::end_pick_box(); + + $scrout .= $advanced_buttons + .''; + + $scrout .= &Apache::loncommon::end_page(); + $r->print($scrout); + return; } ###################################################################### @@ -556,316 +846,288 @@ 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 %save = %{shift()}; - my $persistent=''; - foreach my $name (keys %save) { - if ($name =~ /^form\./ && $name !~ /submit/) { - my @values = (ref($save{$name}) ? @{$save{$name}} : ($save{$name})); - $name=~s/^form\.//; - foreach (@values) { - s/\"/\'/g; # do not mess with html field syntax - next if (! $_ ); - $persistent.=< -END - } - } - } - return $persistent; +sub titlefield { + my $title=shift; + return $title; } ###################################################################### -# HTML form building functions # ###################################################################### =pod -=item HTML form building functions - -=over 4 - -=cut - -############################################### -############################################### - -=pod - -=item &simpletextfield() +=item viewoptiontext() -Inputs: $name,$value,$size +Inputs: codename for view option -Returns a text input field with the given name, value, and size. -If size is not specified, a value of 20 is used. +Outputs: displayed text =cut -############################################### -############################################### - -sub simpletextfield { - my ($name,$value,$size)=@_; - $size = 20 if (! defined($size)); - return ''; -} - -############################################### -############################################### - -=pod - -=item &simplecheckbox() - -Inputs: $name,$value - -Returns a simple check box with the given $name. -If $value eq 'on' the box is checked. - -=cut - -############################################### -############################################### - -sub simplecheckbox { - my ($name,$value)=@_; - my $checked=''; - $checked="checked" if $value eq 'on'; - return ''; +###################################################################### +###################################################################### +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', + 'summarypreview' => 'Summary Preview', + 'detailedpreview' => 'Detailed Citation Preview'); + return $desc{$code}; } -############################################### -############################################### +###################################################################### +###################################################################### -=pod +=pod -=item &fieldtitle() +=item viewoptions() -Input: $title +Inputs: none -Returns a scalar with html which will display $title as a search -field heading. +Outputs: text for box with view options =cut -############################################### -############################################### - -sub fieldtitle { - my $title = uc(shift()); - return ''.$title. - ': '; +###################################################################### +###################################################################### +sub viewoptions { + my $scrout; + if (! defined($env{'form.viewselect'})) { + $env{'form.viewselect'}='detailed'; + } + $scrout .= '' + .&mt('Type:').' ' + .&Apache::lonmeta::selectbox('viewselect', + $env{'form.viewselect'}, + \&viewoptiontext, + sort(keys(%Views))) + .''; + my $countselect = &Apache::lonmeta::selectbox('show', + $env{'form.show'}, + undef, + (10,20,50,100,1000,10000)); + $scrout .= ' ' + .&mt('Records per Page:').' '.$countselect + .''.$/; + return $scrout; } -############################################### -############################################### +###################################################################### +###################################################################### -=pod +=pod -=item &searchphrasefield() +=item searchhelp() -Inputs: $title,$name,$value +Inputs: none -Returns html for a title line and an input field for entering search terms. -The entry field (which is where the $name and $value are used) is a 50 column -simpletextfield. The html returned is for a row in a three column table. +Outputs: return little blurb on how to enter searches =cut -############################################### -############################################### - -sub searchphrasefield { - my ($title,$name,$value)=@_; - return ''.&fieldtitle($title).''. - &simpletextfield($name,$value,50)." \n"; +###################################################################### +###################################################################### +sub searchhelp { + return &mt('Enter words and quoted phrases'); } -############################################### -############################################### - -=pod - -=item &searchphrasefield_with_related() - -Inputs: $title,$name,$value - -Returns html for a title line and an input field for entering search terms -and a check box for 'related words'. The entry field (which is where the -$name and $value are used) is a 50 column simpletextfield. The name of -the related words checkbox is "$name_related". - -=cut +###################################################################### +###################################################################### -############################################### -############################################### - -sub searchphrasefield_with_related { - my ($title,$name,$value)=@_; - return ''.&fieldtitle($title).''. - &simpletextfield($name,$value,50).' '. - &simplecheckbox($name.'_related',$ENV{'form.'.$name.'_related'}). - " \n"; -} +=pod -############################################### -############################################### +=item &get_persistent_form_data() -=pod +Inputs: filename of database -=item &dateboxes() +Outputs: returns undef on database errors. -Returns html selection form elements for the specification of -the day, month, and year. +This function is the reverse of &make_persistent() for form data. +Retrieve persistent data from %persistent_db. Retrieved items will have their +values unescaped. If a form value already exists in $env, it will not be +overwritten. Form values that are array references may have values appended +to them. =cut -############################################### -############################################### - -sub dateboxes { - my ($name,$defaultmonth,$defaultday,$defaultyear, - $currentmonth,$currentday,$currentyear)=@_; - ($defaultmonth,$defaultday,$defaultyear)=('','',''); +###################################################################### +###################################################################### +sub get_persistent_form_data { + my $filename = shift; + return 0 if (! -e $filename); + return undef if (! tie(%persistent_db,'GDBM_File',$filename, + &GDBM_READER(),0640)); # - # Day - my $day=< - -END - for (my $i = 1; $i<=31; $i++) { - $day.="\n"; - } - $day.="\n"; - $day=~s/(\"$currentday\")/$1 SELECTED/ if length($currentday); + # These make sure we do not get array references printed out as 'values'. + my %arrays_allowed = ('form.domains'=>1); # - # Month - my $month=< - -END - my $i = 1; - foreach (qw/January February March April May June - July August September October November December /){ - $month .="\n"; - $i++; - } - $month.="\n"; - $month=~s/(\"$currentmonth\")/$1 SELECTED/ if length($currentmonth); - # - # Year (obviously) - my $year=< - -END - my $maxyear = 2051; - for (my $i = 1976; $i<=$maxyear; $i++) { - $year.="\n"; + # Loop through the keys, looking for 'form.' + foreach my $name (keys(%persistent_db)) { + next if ($name !~ /^form./); + # Kludgification begins! + if ($name eq 'form.domains' && + $env{'form.searchmode'} eq 'basic' && + $env{'form.phase'} ne 'disp_basic') { + next; + } + # End kludge (hopefully) + next if (exists($env{$name})); + my @values = map { + &unescape($_); + } split(',',$persistent_db{$name}); + next if (@values <1); + if ($arrays_allowed{$name}) { + $env{$name} = [@values]; + } else { + $env{$name} = $values[0] if ($values[0]); + } } - $year.="\n"; - $year=~s/(\"$currentyear\")/$1 SELECTED/ if length($currentyear); - return "$month$day$year"; + untie (%persistent_db); + return 1; } -############################################### -############################################### - -=pod - -=item &selectbox() - -Returns a scalar containing an html tag. +=pod -=item $default +=item &get_persistent_data() -The default value of the form. Can be $anyvalue, or in @idlist. +Inputs: filename of database, ref to array of values to recover. -=item $anyvalue +Outputs: array of values. Returns undef on error. -The