--- loncom/interface/lonsearchcat.pm 2002/06/27 14:46:00 1.132 +++ loncom/interface/lonsearchcat.pm 2025/03/19 15:44:44 1.364 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Search Catalog # -# $Id: lonsearchcat.pm,v 1.132 2002/06/27 14:46:00 matthew Exp $ +# $Id: lonsearchcat.pm,v 1.364 2025/03/19 15:44:44 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 -# ############################################################################### ############################################################################### @@ -40,7 +32,7 @@ =head1 NAME -lonsearchcat +lonsearchcat - LONCAPA Search Interface =head1 SYNOPSIS @@ -56,256 +48,596 @@ 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 -=over 4 - =cut ############################################################################### ############################################################################### -############################################################################### -## ## -## 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 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(); +use Parse::RecDescent; +use Apache::lonnavmaps; +use Apache::lonindexer(); +use Apache::lonwishlist(); +use LONCAPA; +use Time::HiRes qw(sleep); ###################################################################### ###################################################################### - -=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 - -###################################################################### -###################################################################### - -=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 +## +## 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 + +# 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 %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(). - $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(0.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"; + 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; + } - &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['catalogmode','launch','acts','mode','form','element', - 'reqinterface']); + 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 $crumb_text; + my @allowed_searches; + if ($env{'form.catalogmode'} eq 'import') { + $env{'form.area'} = 'res'; + $crumb_text = 'Content Library Search'; + } else { + push(@allowed_searches,'portfolio'); + } + if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'}) eq 'F') { + push(@allowed_searches,'res'); + } else { + unless ($env{'form.catalogmode'} eq 'import') { + $env{'form.area'} = 'portfolio'; + $crumb_text = 'Portfolio Search'; + } + } + if (@allowed_searches ==2) { + unless (($env{'form.area'} eq 'portfolio') || ($env{'form.area'} eq 'res')) { + delete($env{'form.area'}); + } + $crumb_text = 'Portfolio and Content Library Search'; + } + my $target = '_top'; + if ((($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) || + (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'} eq '_self'))) { + if ($env{'form.phase'} =~ /^(sort|run_search)$/) { + $target = '_parent'; + } else { + $target = '_self'; + } + } + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/searchcat?'. + &Apache::loncommon::inhibit_menu_check(). + '&catalogmode='.$env{'form.catalogmode'}. + '&launch='.$env{'form.launch'}. + '&mode='.$env{'form.mode'}. + '&area='.$env{'form.area'}, + text=>"$crumb_text", + target=>$target, + 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 = + &mt('We were unable to retrieve data describing your search.'). + ' '.&mt('This is a serious error and has been logged.'). + '
'. + &mt('Please alert your LON-CAPA administrator.'); + &Apache::loncommon::simple_error_page( + $r,'Search Error', + $msg, + {'no_auto_mt_msg' => 1}); + return OK; + } + } + } else { + &clean_up_environment(); + } ## - ## Clear out old values from database + ## Clear out old values from groupsearch database ## - if ($ENV{'form.launch'} eq '1') { - if (tie(%hash,'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 %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. + 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 = ''; } - $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,$hidden); - } elsif ($ENV{'form.advancedsubmit'} eq 'SEARCH') { - # Perform advanced search and give results - return &advancedsearch($r,$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'})) { + $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'; + } + # + if ($env{'form.searchmode'} eq 'advanced') { + my $srchtype = 'Content Library'; + 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'}. + '&area='.$env{'form.area'}, + text=>"Advanced $srchtype Search", + bug=>'Searching',}); + } elsif (($env{'form.phase'} eq 'results') || + ($env{'form.phase'} =~ /^(sort|run_search)$/)) { + &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'}. + '&area='.$env{'form.area'}. + '&searchmode='.$env{'form.searchmode'}, + text=>"Search Results", + 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,$target); + } elsif ($env{'form.phase'} eq 'run_search') { + &run_search($r,$query,$customquery,$customshow, + $libraries,$pretty_string,$env{'form.area'},$domainsref,$target); + } + } 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 ($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)); + } + &make_persistent({ query => $query, + customquery => $customquery, + customshow => $customshow, + libraries => $libraries, + pretty_string => $pretty_string, + domains => $domains }, + $persistent_db_file); + # + # 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 ''.$/; +} + +sub start_search_tabs { + my $area; + my %lt = &Apache::lonlocal::texthash ( + res => 'Content Library Search', + portfolio => 'Portfolio Search', + ); + my $output = ''; + } + } else { + $area = 'portfolio'; + $output .= "\n".'
  • '. + '    '.$lt{'portfolio'}. + '    
  • '; + } + $output .= '
    '. + '
    '. + '
    '; + return $output; +} + +sub end_search_tabs { + return '
    '; +} -###################################################################### ###################################################################### -=pod +=pod -=item &basic_search_form() +=over 4 + +=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 print_basic_search_form { + my ($r,$closebutton,$hidden_fields) = @_; + my %lt = &Apache::lonlocal::texthash ( + res => 'Content Library Search', + portfolio => 'Portfolio Search', + ); + my $result = ($env{'form.catalogmode'} ne 'import'); + my $area; + my $bread_crumb = + &Apache::lonhtmlcommon::breadcrumbs('Searching','Search_Basic', + $env{'form.catalogmode'} ne 'import'); + my $scrout = &Apache::loncommon::start_page('Content Library').$bread_crumb. + '
    '."\n". + &start_search_tabs(); + if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'}) eq 'F') { + if ($env{'form.area'} eq 'portfolio') { +# Search form for accessible portfolio files + $scrout .= &setup_basic_search($r,'portfolio',$hidden_fields,$closebutton); + } else { +# Search form for resource space + $scrout .= &setup_basic_search($r,'res',$hidden_fields,$closebutton); + } + } else { +# Search form for accessible portfolio files + $scrout .= &setup_basic_search($r,'portfolio',$hidden_fields,$closebutton); + } + $scrout .= &end_search_tabs().&Apache::loncommon::end_page(); + $r->print($scrout); + return; +} -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'; - $scrout.=<Advanced Search
    -

    -

      -$closebutton - - - - -

    -
    - - -ENDDOCUMENT + my $singledom; + my ($disabled,$checked); + if ($anydom) { + $singledom = $r->dir_config('lonDefDomain'); + if ($env{'form.domains'} eq $singledom) { + $checked = 1; + } + } else { + $singledom = $env{'user.domain'}; + $disabled = ' disabled="disabled"'; + $checked = 1; + } + $onlysearchdomain = ''; + + $adv_search_link = ''.&mt('Advanced Search').''; + # + $scrout.='
    '. + ''. + $hidden_fields; + if (!exists($env{'form.area'})) { + $scrout .= ''; + } + # + $scrout .= '
    '. + '
    '. + '
    '. + ''.(' 'x3).$adv_search_link.''.'
    '. + ''.(' 'x1).$userelatedwords.''.'
    '. + ''.(' 'x1).$onlysearchdomain.''.'
    '. + ''.(' 'x1).$inclext.''.'
    '. + '

    '.$/; + # + $scrout .= '

    ' + .&viewoptions() + .'

    ' + .'

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

    '; + # + $scrout .= '
    '; return $scrout; -} +} + ###################################################################### ###################################################################### @@ -313,191 +645,351 @@ 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 - my $scrout=<<"ENDHEADER"; - - -The LearningOnline Network with CAPA -'; + } + my $scrout= &Apache::loncommon::start_page("Advanced $srchtype Search", + $jscript); + $scrout .= $bread_crumb.'
    '."\n". + &start_search_tabs(); + + $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('') + .&Apache::lonmeta::prettyinput($field, + $env{'form.'.$field},'', + $field, + 'advsearch', + $related_word_search{$field}, + '  ', + $env{'form.'.$field.'_related'}, + 50); + if ($related_word_search{$field}) { + $scrout .= ''; + } 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 - - - -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.="
    VIEW: - - - -
      
      
    \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'. - # - 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.=''. - '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; + foreach my $field ('lowestgradelevel','highestgradelevel') { + $scrout .= &Apache::lonhtmlcommon::row_title('') + .&Apache::lonmeta::prettyinput($field, + $env{'form.'.$field},'', + $field, + 'advsearch', + 0) + .&Apache::lonhtmlcommon::row_closure(); + } + + $scrout .= &Apache::lonhtmlcommon::row_title('') + .&Apache::loncommon::filecategoryselect('category', + $env{'form.category'},'category') + .&Apache::lonhtmlcommon::row_closure(); + + my $anydomain = 1; + if ($env{'form.area'} ne 'portfolio') { + unless (&Apache::lonnet::allowed('bre','/res/')) { + $anydomain = 0; + } + } + + $scrout .= &Apache::lonhtmlcommon::row_title(''); + if ($anydomain) { + my $defdom = &Apache::lonnet::default_login_domain(); + my ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('shared',$defdom); + $scrout .= &Apache::loncommon::domain_select('domains', + $env{'form.domains'},1,$trusted,$untrusted,'domains'); + } else { + $scrout .= &Apache::loncommon::select_dom_form($env{'user.domain'}, + 'domains','','','', + [$env{'user.domain'}],'',1,'domains'); + } + $scrout .= &Apache::lonhtmlcommon::row_closure(); + + # Misc metadata + if ($env{'form.area'} ne 'portfolio') { + $scrout .= &Apache::lonhtmlcommon::row_title('') + .&Apache::lonmeta::selectbox('copyright', + $env{'form.copyright'},'', + 'copyright', + \&Apache::loncommon::copyrightdescription, + ( undef, + &Apache::loncommon::copyrightids) + ) + .&Apache::lonhtmlcommon::row_closure(); + } + + $scrout .= &Apache::lonhtmlcommon::row_title('') + .&Apache::lonmeta::selectbox('language', + $env{'form.language'},'','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; + } + my $customlabel = &mt('Text box description'); + $scrout .= &Apache::lonhtmlcommon::row_headline() + .'

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

    ' + .&Apache::lonhtmlcommon::row_closure() + .&Apache::lonhtmlcommon::row_title(''.$customlabel.'', + '','','',1) + .&mt('Field Name').' | '.&mt('Field Value(s)') + .&Apache::lonhtmlcommon::row_closure(); + + for (my $j=0; $j<$curnumadd; $j++) { + my $num = $j+1; + my $namelabel = &mt('name of custom metadata field [_1]',$num); + my $valuelabel = &mt('value of custom metadata field [_1]',$num); + $scrout .= &Apache::lonhtmlcommon::row_title(&mt('Custom metadata [_1]',$num)) + .'' + .' ' + .'' + .&Apache::lonhtmlcommon::row_closure(); + } + my $addcustomlabel = &mt('Add metadata field option'); + $scrout .= &Apache::lonhtmlcommon::row_title(''.$addcustomlabel.'', + '','','',1) + .'' + .'' + .&Apache::lonhtmlcommon::row_closure(); +} else { + # + # Dynamic metadata + my $statslabel = &mt('Text box description'); + $scrout .= &Apache::lonhtmlcommon::row_headline() + .'

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

    ' + .&Apache::lonhtmlcommon::row_closure(); + $scrout .= &Apache::lonhtmlcommon::row_title(''.$statslabel.'', + '','','',1) + .&mt('Minimum').' | '.&mt('Maximum') + .&Apache::lonhtmlcommon::row_closure(); + foreach my $statistic + ({ name=>'count', + description=>'Network-wide number of accesses (hits)', + minlabel => 'minimum hit count', + maxlabel => 'maximum hit count'}, + { name=>'stdno', + description=> + 'Statistics calculated for number of students', + minlabel => 'minimum number of students in calculation', + maxlabel => 'maximum number of students in calculation'}, + { name => 'avetries', + description=>'Average number of tries till solved', + minlabel => 'minimum average tries till solved', + maxlabel => 'maximum average tries till solved'}, + { name => 'difficulty', + description=>'Degree of difficulty', + minlabel => 'minimum degree of difficulty', + maxlabel => 'maximum degree of difficulty'}, + { name => 'disc', + description=>'Degree of discrimination', + minlabel => 'minimum degree of discrimination', + maxlabel => 'maximum degree of discrimination'}) { + $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt($statistic->{'description'}))) + .'' + .' ' + .'' + .&Apache::lonhtmlcommon::row_closure(); + } + my $evallabel = &mt('Text box description'); + $scrout .= &Apache::lonhtmlcommon::row_headline() + .'

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

    ' + .&Apache::lonhtmlcommon::row_closure(); + $scrout .= &Apache::lonhtmlcommon::row_title(''.$evallabel.'', + '','','',1) + .&mt('Minimum').' | '.&mt('Maximum') + .&Apache::lonhtmlcommon::row_closure(); + foreach my $evaluation + ( { name => 'clear', + description => 'Material presented in clear way', + minlabel => 'minimum score: clarity', + maxlabel => 'maximum score: clarity'}, + { name =>'depth', + description => 'Material covered with sufficient depth', + minlabel => 'minimum score: coverage depth', + maxlabel => 'maximum score: coverage depth'}, + { name => 'helpful', + description => 'Material is helpful', + minlabel => 'minimum score: content helpful', + maxlabel => 'maximum score: content helpful'}, + { name => 'correct', + description => 'Material appears to be correct', + minlabel => 'minimum score: correctness', + maxlabel => 'maximum score: correctness'}, + { name => 'technical', + description => 'Resource is technically correct', + minlabel => 'minimum score: technical correctness', + maxlabel => 'maximum score: technical correctness'}) { + $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt($evaluation->{'description'}))) + .'' + .' ' + .'' + .&Apache::lonhtmlcommon::row_closure(); + } + } + # + # Creation/Modification date limits + my $dateslabel = &mt('Text box description'); + $scrout .= &Apache::lonhtmlcommon::row_headline() + .'

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

    ' + .&Apache::lonhtmlcommon::row_closure(); + $scrout .= &Apache::lonhtmlcommon::row_title(''.$dateslabel.'', + '','','',1) + .&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 .= &end_search_tabs().'
    '.&Apache::loncommon::end_page(); + $r->print($scrout); + return; } ###################################################################### @@ -505,204 +997,287 @@ ENDDOCUMENT =pod -=item &make_persistent() +=item &titlefield() + +Inputs: title text -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. +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', + 'summarypreview' => 'Summary Preview', + 'detailedpreview' => 'Detailed Citation Preview'); + 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 .= ''; + my $countselect = &Apache::lonmeta::selectbox('show', + $env{'form.show'},'','', + undef, + (10,20,50,100,1000,10000)); + $scrout .= ' '.$/; + 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
    '.&Apache::loncommon::end_page()); +# if ($env{'form.catalogmode'} ne 'import') { + $r->print(< +window.location='/adm/searchcat?phase=sort&area=$env{"form.area"}&catalogmode=$env{"form.catalogmode"}&persistent_db_id=$env{"form.persistent_db_id"}'; + +SCRIPT +# } + return; +} + +###################################################################### +###################################################################### + +=pod + +=item &prev_next_buttons() + +Returns html for the previous and next buttons on the search results page. + +=cut + +###################################################################### +###################################################################### +sub prev_next_buttons { + my ($current_min,$show,$total,$parms) = @_; + return '' if ($show eq 'all'); # No links if you get them all at once. + # + # Create buttons + return '

    ' + .'' + .' ' + .'' + .' ' + .'' + .'

    '; +} + +###################################################################### +###################################################################### + +=pod + +=item &display_results() + +Prints the results out for selection and perusal. + +=cut + +###################################################################### +###################################################################### +sub display_results { + my ($r,$importbutton,$closebutton,$diropendb,$area) = @_; + my $connection = $r->connection; + $r->print(&search_results_header($importbutton,$closebutton)); + ## + ## Set viewing function + ## + my $viewfunction = $Views{$env{'form.viewselect'}}; + if (!defined($viewfunction)) { + $r->print('

    ' + .&mt('Internal Error - Bad view selected.') + .'

    '."\n" + .''.&Apache::loncommon::end_page()); + $r->rflush(); + return; + } + ## + ## $checkbox_num is a count of the number of checkboxes output on the + ## page this is used only during catalogmode=import. + my $checkbox_num = 0; + ## + ## Get the catalog controls setup + ## + my $action = '/adm/searchcat?phase=results&area='.$env{'form.area'}. + '&catalogmode='.$env{'form.catalogmode'}; + ## + ## Deal with import by opening the import db file. + if ($env{'form.catalogmode'} eq 'import') { + if (! tie(%groupsearch_db,'GDBM_File',$diropendb, + &GDBM_WRCREAT(),0640)) { + # NOTE: this can happen when a previous request to searchcat?phase=results gets interrupted + # (%groupsearch_db is not untied) + $r->print('

    '. + &mt('Unable to save import results.'). + '

    '. + ''. + &Apache::loncommon::end_page()); + $r->rflush(); + return; + } + # untie %groupsearch_db if the connection gets aborted before the end + $r->register_cleanup(sub { + untie %groupsearch_db if (tied(%groupsearch_db)); + }); + } + ## + ## Prepare the table for querying + my $table = $env{'form.table'}; + return if (! &ensure_db_and_table($r,$table)); + ## + ## Get the number of results + my $total_results = &Apache::lonmysql::number_of_rows($table); + if (! defined($total_results)) { + $r->print('

    '. + &mt('A MySQL error has occurred.'). + '

    '. + ''. + &Apache::loncommon::end_page()); + &Apache::lonnet::logthis("lonmysql was unable to determine the number". + " of rows in table ".$table); + &Apache::lonnet::logthis(&Apache::lonmysql::get_error()); + return; + } + ## + ## Determine how many results we need to get + $env{'form.start'} = 1 if (! exists($env{'form.start'})); + $env{'form.show'} = 20 if (! exists($env{'form.show'})); + if (exists($env{'form.prev'})) { + $env{'form.start'} -= $env{'form.show'}; + } elsif (exists($env{'form.next'})) { + $env{'form.start'} += $env{'form.show'}; + } + $env{'form.start'} = 1 if ($env{'form.start'}<1); + $env{'form.start'} = $total_results if ($env{'form.start'}>$total_results); + my $min = $env{'form.start'}; + my $max; + if ($env{'form.show'} eq 'all') { + $max = $total_results ; + } else { + $max = $min + $env{'form.show'} - 1; + $max = $total_results if ($max > $total_results); + } + ## + ## Output form elements + $r->print(&hidden_field('table'). + &hidden_field('phase'). + &hidden_field('persistent_db_id'). + &hidden_field('start'). + &hidden_field('area') + ); + # + # Build sorting selector + my @fields = + ( + {key=>'default' }, + {key=>'title' }, + {key =>'author' }, + {key =>'subject'}, + {key =>'url',desc=>'URL'}, + {key =>'keywords'}, + {key =>'language'}, + {key =>'creationdate'}, + {key =>'lastrevisiondate'}, + {key =>'owner'}, + {key =>'copyright'}, + {key =>'authorspace'}, + {key =>'lowestgradelevel'}, + {key =>'highestgradelevel'}, + {key =>'standards',desc=>'Standards'}, + ); + if ($area eq 'portfolio') { + push(@fields, + ( + {key => 'scope'}, + {key => 'keynum'}, + )); + } else { + push(@fields, + ( + {key =>'count',desc=>'Number of accesses'}, + {key =>'stdno',desc=>'Students Attempting'}, + {key =>'avetries',desc=>'Average Number of Tries'}, + {key =>'difficulty',desc=>'Mean Degree of Difficulty'}, + {key =>'disc',desc=>'Mean Degree of Discrimination'}, + {key =>'clear',desc=>'Evaluation: Clear'}, + {key =>'technical',desc=>'Evaluation: Technically Correct'}, + {key =>'correct',desc=>'Evaluation: Material is Correct'}, + {key =>'helpful',desc=>'Evaluation: Material is Helpful'}, + {key =>'depth',desc=>'Evaluation: Material has Depth'}, + )); + } + my %fieldnames = &Apache::lonmeta::fieldnames(); + my @field_order; + foreach my $field_data (@fields) { + push(@field_order,$field_data->{'key'}); + if (! exists($field_data->{'desc'})) { + $field_data->{'desc'}=$fieldnames{$field_data->{'key'}}; + } else { + if (! defined($field_data->{'desc'})) { + $field_data->{'desc'} = ucfirst($field_data->{'key'}); + } + $field_data->{'desc'} = &mt($field_data->{'desc'}); + } + } + my %sort_fields = map {$_->{'key'},$_->{'desc'}} @fields; + $sort_fields{'select_form_order'} = \@field_order; + $env{'form.sortorder'} = 'desc' if (! exists($env{'form.sortorder'})); + if (! exists($env{'form.sortfield'})) { + if ($area eq 'portfolio') { + $env{'form.sortfield'} = 'owner'; + } else { + $env{'form.sortfield'} = 'count'; + } + } + if (! exists($env{'form.sortorder'})) { + if ($env{'form.sortfield'}=~/^(count|stdno|disc|clear|technical|correct|helpful)$/) { + $env{'form.sortorder'}='desc'; + } else { + $env{'form.sortorder'}='asc'; } - my $percent=sprintf('%3.0f',($servercount/$servernum*100)); - } # End of foreach loop over servers remaining - } # End of big loop - while($serversleft && $timeremain) - unless ($resultflag) { - $r->print("\nThere were no results that matched your query\n"); } -# $r->print(''."\n"); $r->rflush(); - $r->print("\n\n"); + my $sortform = '' + .&mt('Sort by:').' ' + .&Apache::loncommon::select_form($env{'form.sortfield'}, + 'sortfield', + \%sort_fields,'','','', + 'LC_sortby') + .' ' + .&Apache::loncommon::select_form($env{'form.sortorder'}, + 'sortorder', + {asc =>&mt('Ascending'), + desc=>&mt('Descending') + },'','','','LC_sortby') + .''; + ## + ## Display links for 'prev' and 'next' pages (if necessary) and Display Options + $r->print('
    '."\n" + .''.&mt('Display Options').''."\n" + .$sortform + .' ' + .&viewoptions() + .'
    ' + .&prev_next_buttons($min,$env{'form.show'},$total_results) + ); + + if ($total_results == 0) { + $r->print('

    '.&mt('There are currently no results.').'

    '. + ''. + &Apache::loncommon::end_page()); + return; + } else { + $r->print('

    '. + mt('Results [_1] to [_2] out of [_3]', + $min,$max,$total_results). + "

    \n"); + } + ## + ## Get results from MySQL table + my $sort_command = 'id>='.$min.' AND id<='.$max; + my $order; + if (exists($env{'form.sortorder'})) { + if ($env{'form.sortorder'} eq 'asc') { + $order = 'ASC'; + } elsif ($env{'form.sortorder'} eq 'desc') { + $order = 'DESC'; + } else { + $order = ''; + } + } else { + $order = ''; + } + if ($env{'form.sortfield'} ne 'default' && + exists($sort_fields{$env{'form.sortfield'}})) { + $sort_command = $env{'form.sortfield'}.' IS NOT NULL '. + 'ORDER BY '.$env{'form.sortfield'}.' '.$order. + ' LIMIT '.($min-1).','.($max-$min+1); + } + my @Results = &Apache::lonmysql::get_rows($table,$sort_command); + ## + ## Loop through the results and output them. + my $tabletype = 'metadata'; + if ($area eq 'portfolio') { + $tabletype = 'portfolio_search'; + } + $r->print(&Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + ''.&mt('Data').''); + if (($env{'form.viewselect'} eq 'detailedpreview') || + ($env{'form.viewselect'} eq 'summarypreview')) { + $r->print(''.&mt('Preview').''); + } + $r->print(&Apache::loncommon::end_data_table_header_row()); + foreach my $row (@Results) { + if ($connection->aborted()) { + &cleanup(); + return; + } + my %Fields = %{&parse_row($tabletype,@$row)}; + my $output; + if (! defined($Fields{'title'}) || $Fields{'title'} eq '') { + $Fields{'title'} = 'Untitled'; + } + my $prefix=&catalogmode_output($Fields{'title'},$Fields{'url'}, + $Fields{'id'},$checkbox_num++); + # Render the result into html + $output.= &$viewfunction($prefix,%Fields); + # Print them out as they come in. + $r->print(&Apache::loncommon::start_data_table_row() + .'' + .$output + .'' + .&Apache::loncommon::end_data_table_row() + ); + $r->rflush(); + } + $r->print(&Apache::loncommon::end_data_table()); + if (@Results < 1) { + $r->print('

    ' + .&mt('There were no results matching your query.') + .'

    '); + } else { + $r->print( + &prev_next_buttons($min,$env{'form.show'},$total_results, + "table=".$env{'form.table'}. + "&phase=results". + "&persistent_db_id=". + $env{'form.persistent_db_id'}) + ); + } + $r->print(''.&Apache::loncommon::end_page()); + $r->rflush(); + untie %groupsearch_db if (tied(%groupsearch_db)); return; } +###################################################################### +###################################################################### + +=pod + +=item &catalogmode_output($title,$url,$fnum,$checkbox_num) + +Returns html needed for the various catalog modes. Gets inputs from +$env{'form.catalogmode'}. Stores data in %groupsearch_db. + +=cut + +###################################################################### +###################################################################### +sub catalogmode_output { + my $output = ''; + my ($title,$url,$fnum,$checkbox_num) = @_; + if ($env{'form.catalogmode'} eq 'interactive') { + $title=~ s/\'/\\\'/g; + if ($env{'form.catalogmode'} eq 'interactive') { + $output.=< + +END + } + } elsif ($env{'form.catalogmode'} eq 'import') { + $groupsearch_db{"pre_${fnum}_link"}=$url; + $groupsearch_db{"pre_${fnum}_title"}=$title; + $output.=< + + +END + } + return $output; +} +###################################################################### +###################################################################### + +=pod + +=item &parse_row() + +Parse a row returned from the database. + +=cut + +###################################################################### +###################################################################### +sub parse_row { + my ($tabletype,@Row) = @_; + my %Fields; + if (! scalar(@Datatypes)) { + &set_up_table_structure($tabletype); + } + for (my $i=0;$i<=$#Row;$i++) { + $Fields{$Datatypes[$i]->{'name'}}=&unescape($Row[$i]); + } + $Fields{'language'} = + &Apache::loncommon::languagedescription($Fields{'language'}); + $Fields{'copyrighttag'} = + &Apache::loncommon::copyrightdescription($Fields{'copyright'}); + $Fields{'mimetag'} = + &Apache::loncommon::filedescription($Fields{'mime'}); + return \%Fields; +} + ########################################################### ########################################################### @@ -1313,13 +3132,10 @@ END =item &parse_raw_result() Takes a line from the file of results and parse it. Returns a hash -with keys for the following fields: -'title', 'author', 'subject', 'url', 'keywords', 'version', 'notes', -'abstract', 'mime', 'lang', 'owner', 'copyright', 'creationdate', -'lastrevisiondate'. +with keys according to column labels In addition, the following tags are set by calling the appropriate -lonnet function: 'language', 'cprtag', 'mimetag'. +lonnet function: 'language', 'copyrighttag', 'mimetag'. The 'title' field is set to "Untitled" if the title field is blank. @@ -1330,60 +3146,13 @@ The 'title' field is set to "Untitled" i ########################################################### ########################################################### sub parse_raw_result { - my ($result,$hostname) = @_; - # Check for a comma - if it is there then we do not need to unescape the - # string. There seems to be some kind of problem with some items in - # the database - the entire string gets sent out unescaped...? - unless ($result =~ /,/) { - $result = &Apache::lonnet::unescape($result); - } - my @fields=map { - &Apache::lonnet::unescape($_); - } (split(/\,/,$result)); - my ($title,$author,$subject,$url,$keywords,$version, - $notes,$abstract,$mime,$lang, - $creationdate,$lastrevisiondate,$owner,$copyright)=@fields; - my %Fields = - ( title => &Apache::lonnet::unescape($title), - author => &Apache::lonnet::unescape($author), - subject => &Apache::lonnet::unescape($subject), - url => &Apache::lonnet::unescape($url), - keywords => &Apache::lonnet::unescape($keywords), - version => &Apache::lonnet::unescape($version), - notes => &Apache::lonnet::unescape($notes), - abstract => &Apache::lonnet::unescape($abstract), - mime => &Apache::lonnet::unescape($mime), - lang => &Apache::lonnet::unescape($lang), - owner => &Apache::lonnet::unescape($owner), - copyright => &Apache::lonnet::unescape($copyright), - creationdate => &Apache::lonnet::unescape($creationdate), - lastrevisiondate => &Apache::lonnet::unescape($lastrevisiondate) - ); - $Fields{'language'} = - &Apache::loncommon::languagedescription($Fields{'lang'}); - $Fields{'copyrighttag'} = - &Apache::loncommon::copyrightdescription($Fields{'copyright'}); - $Fields{'mimetag'} = - &Apache::loncommon::filedescription($Fields{'mime'}); - # Put spaces in the keyword list, if needed. - $Fields{'keywords'}=~ s/,([A-z])/, $1/g; - if ($Fields{'title'}=~ /^\s*$/ ) { - $Fields{'title'}='Untitled'; - } - unless ($ENV{'user.adv'}) { - $Fields{'keywords'} = '- not displayed -'; - $Fields{'notes'} = '- not displayed -'; - $Fields{'abstract'} = '- not displayed -'; - $Fields{'subject'} = '- not displayed -'; - } - if (length($Fields{'abstract'})>200) { - $Fields{'abstract'} = - substr($Fields{'abstract'},0,200).'...'; - } - if (length($Fields{'keywords'})>200) { - $Fields{'keywords'} = - substr($Fields{'keywords'},0,200).'...'; - } + my ($result,$hostname,$tabletype) = @_; + # conclude from self to others regarding fields + my %Fields=&LONCAPA::lonmetadata::metadata_col_to_hash + ($tabletype, + map { + &unescape($_); + } (split(/\,/,$result)) ); return %Fields; } @@ -1403,8 +3172,8 @@ sub handle_custom_fields { my $customshow=''; my $extrashow=''; my @customfields; - if ($ENV{'form.customshow'}) { - $customshow=$ENV{'form.customshow'}; + if ($env{'form.customshow'}) { + $customshow=$env{'form.customshow'}; $customshow=~s/[^\w\s]//g; my @fields=map { "$_:"; @@ -1420,7 +3189,7 @@ sub handle_custom_fields { if ($result=~/^(custom\=.*)$/) { # grab all custom metadata my $tmp=$result; $tmp=~s/^custom\=//; - my ($k,$v)=map {&Apache::lonnet::unescape($_); + my ($k,$v)=map {&unescape($_); } split(/\,/,$tmp); $customhash{$k}=$v; } @@ -1433,12 +3202,12 @@ sub handle_custom_fields { =pod -=item &search_results_header +=item &search_results_header() Output the proper html headers and javascript code to deal with different calling modes. -Takes most inputs directly from %ENV, except $mode. +Takes most inputs directly from %env, except $mode. =over 4 @@ -1452,7 +3221,7 @@ The following environment variables are =item 'form.catalogmode' -Checked for 'interactive' and 'groupsearch'. +Checked for 'interactive' and 'import'. =item 'form.mode' @@ -1460,8 +3229,16 @@ Checked for existance & 'edit' mode. =item 'form.form' +Contains the name of the form that has the input fields to set + =item 'form.element' +the name of the input field to put the URL into + +=item 'form.titleelement' + +the name of the input field to put the title into + =back =cut @@ -1469,204 +3246,250 @@ Checked for existance & 'edit' mode. ###################################################################### ###################################################################### sub search_results_header { - my ($mode) = @_; - $mode = lc($mode); - my $title; - if ($mode eq 'advanced') { - $title = "Advanced Search Results"; - } elsif ($mode eq 'basic') { - $title = "Basic Search Results"; - } - my $result = ''; + my ($importbutton,$closebutton) = @_; + + my $js; # output beginning of search page - $result.=< - -$title -BEGINNING # conditional output of script functions dependent on the mode in # which the search was invoked - if ($ENV{'form.catalogmode'} eq 'interactive'){ - if (! exists($ENV{'form.mode'}) || $ENV{'form.mode'} ne 'edit') { - $result.=< +// SCRIPT - } elsif ($ENV{'form.mode'} eq 'edit') { - my $form = $ENV{'form.form'}; - my $element = $ENV{'form.element'}; - $result.=< +// SCRIPT } } - $result.=< SCRIPT - $result.=< - function displayinfo(val) { - popwin.document.forms.popremain.sdetails.value=val; - } - function openhelp(val) { - openhelpwin=open('/adm/help/searchcat.html','helpscreen', - 'scrollbars=1,width=400,height=300'); - openhelpwin.focus(); - } - function abortsearch(val) { - popwin.close(); - } + \$(document).ready(function() { + parent.done_loading_results(); + }); SCRIPT - $result.=< - - -

    $title

    + + my $start_page = &Apache::loncommon::start_page(undef,$js, + {'only_body' =>1, + 'add_wishlist' =>1, + 'add_modal' =>1}); + my $result=< +
    +$importbutton END return $result; } +sub results_link { + my $basic_link = "/adm/searchcat?"."&table=".$env{'form.table'}. + "&area=".$env{'form.area'}. + "&catalogmode=".$env{'form.catalogmode'}. + "&persistent_db_id=".$env{'form.persistent_db_id'}; + my $results_link = $basic_link."&phase=results". + "&pause=1"."&start=1"; + return $results_link; +} + ###################################################################### ###################################################################### +sub print_frames_interface { + my $r = shift; + my $basic_link = "/adm/searchcat?table=".$env{'form.table'}. + "&area=".$env{'form.area'}. + "&catalogmode=".$env{'form.catalogmode'}. + "&persistent_db_id=".$env{'form.persistent_db_id'}; + my $run_search_link = $basic_link."&phase=run_search"; + my $results_link = &results_link(); + my $js = < +// + +JS -=pod + my $start_page = + &Apache::loncommon::start_page('LON-CAPA Digital Library Search Results', + $js, + {'frameset' => 1, + 'add_entries' => { + 'rows' => "150,*",},}); + my $end_page = + &Apache::loncommon::end_page({'frameset' => 1}); + + my $result = <<"ENDFRAMES"; +$start_page + + +$end_page +ENDFRAMES -=item &make_popwin() + $r->print($result); + return; +} -Returns html with javascript in it to open up the status window. +###################################################################### +###################################################################### -=cut +sub has_stat_data { + my ($values) = @_; + if ( (defined($values->{'count'}) && $values->{'count'} ne '') || + (defined($values->{'stdno'}) && $values->{'stdno'} ne '') || + (defined($values->{'disc'}) && $values->{'disc'} ne '') || + (defined($values->{'avetries'}) && $values->{'avetries'} ne '') || + (defined($values->{'difficulty'}) && $values->{'difficulty'} ne '')) { + return 1; + } + return 0; +} + +sub statfields { + return ('count','stdno','disc','avetries','difficulty'); +} + +sub has_eval_data { + my ($values) = @_; + if ( (defined($values->{'clear'}) && $values->{'clear'} ne '') || + (defined($values->{'technical'}) && $values->{'technical'} ne '') || + (defined($values->{'correct'}) && $values->{'correct'} ne '') || + (defined($values->{'helpful'}) && $values->{'helpful'} ne '') || + (defined($values->{'depth'}) && $values->{'depth'} ne '')) { + return 1; + } + return 0; +} + +sub evalfields { + return ('clear','technical','correct','helpful','depth'); +} ###################################################################### ###################################################################### -sub make_popwin { - my %rhash = @_; - my $servernum=(keys %rhash); - my $hcinit; - my $grid="'
    '+\n"; - # $sn is the server number, used ONLY to make sure we have - # rows of 10 each. No longer used to index images. - my $sn=1; - foreach my $sk (sort keys %rhash) { - # ''+ - $grid.="'+\"'\"+')\">'+"; - $grid.="\n"; - $grid.="'\"".$sk.'+\n"; - $grid.="'
    '+\n" unless $sn%10; - $sn++; - } - my $result.=< - popwin=open('','popwin','scrollbars=1,width=400,height=220'); - popwin.focus(); - popwin.document.writeln('<'+'html>'); - popwin.document.writeln('<'+'head>'); - popwin.document.writeln('<'+'script>'); - popwin.document.writeln('hc=new Array();$hcinit'); - popwin.document.writeln('<'+'/script>'); - popwin.document.writeln('<'+'/head>'+ - '<'+'body bgcolor="#FFFFFF">'+ - '<'+'image name="whirly" align="right" src="/adm/lonIcons/'+ - 'lonanim.gif" '+ - 'alt="animated logo" />'+ - '<'+'h3>Search Results Progress<'+'/h3>'+ - '<'+'form name="popremain">'+ - '<'+'tt>'+ - '<'+'br clear="all"/>PLEASE BE PATIENT'+ - '<'+'br />SCANNING $servernum SERVERS'+ - '<'+'br clear="all" />Number of record hits found '+ - '<'+'input type="text" size="10" name="numhits"'+ - ' value="0" />'+ - '<'+'br clear="all" />Time elapsed '+ - '<'+'input type="text" size="10" name="elapsetime"'+ - ' value="0" />'+ - '<'+'br />'+ - 'SERVER GRID (click on any cell for details)'+ - $grid - '<'+'br />'+ - 'Server details '+ - '<'+'input type="text" size="35" name="sdetails"'+ - ' value="" />'+ - '<'+'br />'+ - ' <'+'input type="button" name="button"'+ - ' value="close this window" '+ - ' onClick="javascript:opener.abortsearch()" />'+ - ' <'+'input type="button" name="button"'+ - ' value="help" onClick="javascript:opener.openhelp()" />'+ - '<'+'/tt>'+ - '<'+'/form>'+ - '<'+'/body><'+'/html>'); - popwin.document.close(); - -ENDPOP + +sub display_tools { + my ($title, $jumpurl) = @_; + my $result; + # Metadata + $result.= + &Apache::loncommon::modal_link( + $jumpurl.'.meta?inhibitmenu=yes', + 'Info', + 500,500,'_blank',undef,&mt('Metadata')); + # Stored Links + $result.= + ' '. + ''; return $result; } @@ -1678,6 +3501,7 @@ ENDPOP =item Metadata Viewing Functions Output is a HTML-ified string. + Input arguments are title, author, subject, url, keywords, version, notes, short abstract, mime, language, creation date, last revision date, owner, copyright, hostname, and @@ -1692,28 +3516,116 @@ extra custom metadata to show. ###################################################################### ###################################################################### sub detailed_citation_view { - my %values = @_; - my $result=<$values{'title'} -

    -$values{'author'}, $values{'owner'}
    - -Subject: $values{'subject'}
    -Keyword(s): $values{'keywords'}
    -Notes: $values{'notes'}
    -MIME Type: $values{'mimetag'}
    -Language: $values{'language'}
    -Copyright/Distribution: $values{'cprtag'}
    -

    -$values{'extrashow'} -

    -$values{'shortabstract'} -

    -END + my ($prefix,%values) = @_; + my $result; + my $jumpurl=$values{'url'}; + $jumpurl=~s|^/ext/|http://|; + $result .= + ''.$prefix. + ''.' '. + ''.$values{'title'}."\n". + &display_tools($values{'title'}, $jumpurl). + "

    \n". + ''.$values{'author'}.','. + ' '.$values{'owner'}.'
    '; + foreach my $field + ( + { name=>'url', + translate => 'URL: [_1]', + special => 'url link',}, + { name=>'subject', + translate => 'Subject: [_1]',}, + { name=>'keywords', + translate => 'Keywords: [_1]',}, + { name=>'notes', + translate => 'Notes: [_1]',}, + { name=>'mimetag', + translate => 'MIME Type: [_1]',}, + { name=>'standards', + translate => 'Standards:[_1]',}, + { name=>'copyrighttag', + translate => 'Copyright/Distribution: [_1]',}, + { name=>'count', + format => "%d", + translate => 'Access Count: [_1]',}, + { name=>'stdno', + format => "%d", + translate => 'Number of Students: [_1]',}, + { name=>'avetries', + format => "%.2f", + translate => 'Average Tries: [_1]',}, + { name=>'disc', + format => "%.2f", + translate => 'Degree of Discrimination: [_1]',}, + { name=>'difficulty', + format => "%.2f", + translate => 'Degree of Difficulty: [_1]',}, + { name=>'clear', + format => "%.2f", + translate => 'Clear: [_1]',}, + { name=>'depth', + format => "%.2f", + translate => 'Depth: [_1]',}, + { name=>'helpful', + format => "%.2f", + translate => 'Helpful: [_1]',}, + { name=>'correct', + format => "%.2f", + translate => 'Correct: [_1]',}, + { name=>'technical', + format => "%.2f", + translate => 'Technical: [_1]',}, + { name=>'comefrom_list', + type => 'list', + translate => 'Resources that lead up to this resource in maps',}, + { name=>'goto_list', + type => 'list', + translate => 'Resources that follow this resource in maps',}, + { name=>'sequsage_list', + type => 'list', + translate => 'Resources using or importing resource',}, + ) { + next if (! exists($values{$field->{'name'}}) || + $values{$field->{'name'}} eq ''); + if (exists($field->{'type'}) && $field->{'type'} eq 'list') { + $result .= ''.&mt($field->{'translate'}).''; + foreach my $item (split(',',$values{$field->{'name'}})){ + $item = &Apache::lonnet::clutter($item); + $result .= '
    '.&display_url($item,1).'
    '; + } + } elsif (exists($field->{'format'}) && $field->{'format'} ne ''){ + $result.= &mt($field->{'translate'}, + sprintf($field->{'format'}, + $values{$field->{'name'}}))."
    \n"; + } else { + if ($field->{'special'} eq 'url link') { + $result .= '
    '.&display_url($jumpurl,1).'
    '; + } else { + $result.= &mt($field->{'translate'}, + $values{$field->{'name'}}); + } + $result .= "
    \n"; + } + } + $result .= "

    "; + if (exists($values{'extrashow'}) && $values{'extrashow'} ne '') { + $result .= '

    '.$values{'extrashow'}.'

    '; + } + if (exists($values{'shortabstract'}) && $values{'shortabstract'} ne '') { + $result .= '

    '.$values{'shortabstract'}.'

    '; + } return $result; } +sub detailed_citation_preview { + my ($prefix,%values)=@_; + return &detailed_citation_view($prefix,%values). + ''. + &Apache::lonindexer::showpreview($values{'url'}); +} + + ###################################################################### ###################################################################### @@ -1722,23 +3634,106 @@ END =item &summary_view() =cut - ###################################################################### ###################################################################### sub summary_view { - my %values = @_; - my $result=<$values{'author'}
    -$values{'title'}
    -$values{'owner'} -- $values{'lastrevisiondate'}
    + my ($prefix,%values) = @_; + my $icon=&Apache::loncommon::icon($values{'url'}); + my $result=qq{$prefix}; + if (exists($env{'form.sortfield'}) && + $env{'form.sortfield'} !~ /^(default| + author| + url| + title| + owner| + lastrevisiondate| + copyright)$/x) { + my $tmp = $values{$env{'form.sortfield'}}; + if (! defined($tmp)) { $tmp = 'undefined'; } + $result .= ' '.$tmp.' '; + } + my $jumpurl=$values{'url'}; + $jumpurl=~s|^/ext/|http://|; + my $link = '
    '.&display_url($jumpurl,1).'
    '; + $result .= + ''.$values{'title'}.''. + &display_tools($values{'title'}, $jumpurl).< +$link
    +$values{'author'}, $values{'owner'} -- $values{'lastrevisiondate'}
    $values{'copyrighttag'}
    $values{'extrashow'} -

    END return $result; } +sub summary_preview { + my ($prefix,%values)=@_; + return &summary_view($prefix,%values). + ''. + &Apache::lonindexer::showpreview($values{'url'}); +} + +###################################################################### +###################################################################### + +=pod + +=item &compact_view() + +=cut + +###################################################################### +###################################################################### +sub compact_view { + my ($prefix,%values) = @_; + my $jumpurl=$values{'url'}; + $jumpurl=~s|^/ext/|http://|; + + my $link = &display_url($jumpurl,1); + + my $result = + $prefix.''; + if (exists($env{'form.sortfield'}) && + $env{'form.sortfield'} !~ /^(default|author|url|title)$/) { + my $tmp = $values{$env{'form.sortfield'}}; + if (! defined($tmp)) { $tmp = 'undefined'; } + $result .= ' '.$tmp.' '; + } + $jumpurl = &HTML::Entities::encode($jumpurl,'<>&"'); + $result.=' '. + ''. + &HTML::Entities::encode($values{'title'},'<>&"').' '. + &display_tools($values{'title'}, $jumpurl). + $link.' '.$values{'author'}.' ('.$values{'domain'}.')'; + return $result; +} + +sub display_url { + my ($url,$skiplast) = @_; + my $link; + if ($url=~m|^/ext/|) { + $url=~s|^/ext/|http://|; + $link=''.$url.''; + } elsif ($url=~m{^(http://|/uploaded/)}) { + $link=''.$url.''; + } else { + # replace the links to open in a new window + # (because the search opens in a new window, it gets + # confusing when the links open a tab in the + # parent window; ideally we should not force windows) + my $onclick = " onclick=\"window.open(this.href, '_blank', 'toolbar=1,location=1,menubar=0');return false;\""; + $link=&Apache::lonhtmlcommon::crumbs( + $url, + 'preview', + '', + '', + $skiplast,$onclick).' '; + } + return $link; +} + ###################################################################### ###################################################################### @@ -1751,27 +3746,42 @@ END ###################################################################### ###################################################################### sub fielded_format_view { - my %values = @_; + my ($prefix,%values) = @_; + my $icon=&Apache::loncommon::icon($values{'url'}); + my %Translated = &Apache::lonmeta::fieldnames(); + my $jumpurl=$values{'url'}; + $jumpurl=~s|^/ext/|http://|; + my $result=<URL: $values{'url'} -
    -Title: $values{'title'}
    -Author(s): $values{'author'}
    -Subject: $values{'subject'}
    -Keyword(s): $values{'keywords'}
    -Notes: $values{'notes'}
    -MIME Type: $values{'mimetag'}
    -Language: $values{'language'}
    -Creation Date: $values{'creationdate'}
    -Last Revision Date: $values{'lastrevisiondate'}
    -Publisher/Owner: $values{'owner'}
    -Copyright/Distribution: $values{'copyrighttag'}
    -Repository Location: $values{'hostname'}
    -Abstract: $values{'shortabstract'}
    -$values{'extrashow'} -

    +$prefix +
    +
    URL:
    +
    $values{'url'} END + $result .= + &display_tools($values{'title'}, $jumpurl).' +
    '; + foreach my $field ('title','author','domain','subject','keywords','notes', + 'mimetag','language','creationdate','lastrevisiondate', + 'owner','copyrighttag','hostname','abstract') { + $result .= (' 'x4).'
    '.$Translated{$field}.'
    '."\n". + (' 'x8).'
    '.$values{$field}.'
    '."\n"; + } + if (&has_stat_data(\%values)) { + foreach my $field (&statfields()) { + $result .= (' 'x4).'
    '.$Translated{$field}.'
    '."\n". + (' 'x8).'
    '.$values{$field}.'
    '."\n"; + } + } + if (&has_eval_data(\%values)) { + foreach my $field (&evalfields()) { + $result .= (' 'x4).'
    '.$Translated{$field}.'
    '."\n". + (' 'x8).'
    '.$values{$field}.'
    '."\n"; + } + } + $result .= "
    \n"; + $result .= $values{'extrashow'}; return $result; } @@ -1789,34 +3799,60 @@ END ###################################################################### ###################################################################### sub xml_sgml_view { - my %values = @_; + my ($prefix,%values) = @_; + my $xml = ''."\n"; + # The usual suspects + foreach my $field ('url','title','author','subject','keywords','notes','domain') { + $xml .= qq{<$field>$values{$field}}."\n"; + } + # + $xml .= "\n"; + foreach my $field ('mime','mimetag') { + $xml .= qq{<$field>$values{$field}}."\n"; + } + $xml .= "\n"; + # + $xml .= "\n"; + foreach my $field ('language','languagetag') { + $xml .= qq{<$field>$values{$field}}."\n"; + } + $xml .= "\n"; + # + foreach my $field ('creationdate','lastrevisiondate','owner') { + $xml .= qq{<$field>$values{$field}}."\n"; + } + # + $xml .= "\n"; + foreach my $field ('copyright','copyrighttag') { + $xml .= qq{<$field>$values{$field}}."\n"; + } + $xml .= "\n"; + $xml .= qq{$values{'hostname'}}. + "\n"; + $xml .= qq{$values{'shortabstract'}}."\n"; + # + if (&has_stat_data(\%values)){ + $xml .= "\n"; + foreach my $field (&statfields()) { + $xml .= qq{<$field>$values{$field}}."\n"; + } + $xml .= "\n"; + } + # + if (&has_eval_data(\%values)) { + $xml .= "\n"; + foreach my $field (&evalfields) { + $xml .= qq{<$field>$values{$field}}."\n"; + } + $xml .= "\n"; + } + # + $xml .= "\n"; + $xml = &HTML::Entities::encode($xml,'<>&'); my $result=< -<LonCapaResource> -<url>$values{'url'}</url> -<title>$values{'title'}</title> -<author>$values{'author'}</author> -<subject>$values{'subject'}</subject> -<keywords>$values{'keywords'}</keywords> -<notes>$values{'notes'}</notes> -<mimeInfo> -<mime>$values{'mime'}</mime> -<mimetag>$values{'mimetag'}</mimetag> -</mimeInfo> -<languageInfo> -<language>$values{'lang'}</language> -<languagetag>$values{'language'}</languagetag> -</languageInfo> -<creationdate>$values{'creationdate'}</creationdate> -<lastrevisiondate>$values{'lastrevisiondate'}</lastrevisiondate> -<owner>$values{'owner'}</owner> -<copyrightInfo> -<copyright>$values{'copyright'}</copyright> -<copyrighttag>$values{'copyrighttag'}</copyrighttag> -</copyrightInfo> -<repositoryLocation>$values{'hostname'}</repositoryLocation> -<shortabstract>$values{'shortabstract'}</shortabstract> -</LonCapaResource> +$xml $values{'extrashow'} END @@ -1837,11 +3873,54 @@ END sub filled { my ($field)=@_; if ($field=~/\S/ && $field ne 'any') { - return 1; + return 1; + } else { + return 0; } - else { - return 0; +} + +###################################################################### +###################################################################### + +=pod + +=item &output_unparsed_phrase_error() + +=cut + +###################################################################### +###################################################################### +sub output_unparsed_phrase_error { + my ($r,$closebutton,$parms,$hidden_fields,$field)=@_; + my $errorstring; + if ($field eq 'basicexp') { + $errorstring = &mt('Unable to understand the search phrase [_1]. Please modify your search.' + ,''.$env{'form.basicexp'}.''); + } else { + $errorstring = &mt('Unable to understand the search phrase [_1]: [_2]' + ,''.$field.'' + ,$env{'form.'.$field}); } + my $heading = &mt('Unparsed Field'); + my $revise = &mt('Revise search request'); + # make query information persistent to allow for subsequent revision + my $start_page = &Apache::loncommon::start_page('Search'); + my $end_page = &Apache::loncommon::end_page(); + $r->print(< +$hidden_fields +$closebutton +
    +

    $heading

    +

    +$errorstring +

    +

    +$revise +

    +$end_page +ENDPAGE } ###################################################################### @@ -1851,41 +3930,51 @@ sub filled { =item &output_blank_field_error() +Output a complete page that indicates the user has not filled in enough +information to do a search. + +Inputs: $r (Apache request handle), $closebutton, $parms. + +Returns: nothing + +$parms is extra information to include in the 'Revise search request' link. + =cut ###################################################################### ###################################################################### sub output_blank_field_error { - my ($r)=@_; - # make query information persistent to allow for subsequent revision - my $persistent=&make_persistent(); + my ($r,$closebutton,$parms,$hidden_fields)=@_; + my $errormsg = &mt('You did not fill in enough information for the search to be started. You need to fill in relevant fields on the search page in order for a query to be processed.'); + my $revise = &mt('Revise Search Request'); + my $heading = &mt('Unactionable Search Query'); + my $start_page = &Apache::loncommon::start_page('Search'); + my $end_page = &Apache::loncommon::end_page(); + if ($closebutton) { + $closebutton = '

    '.$closebutton.'


    '; + } else { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'', + text=>$heading,}); + $start_page .= &Apache::lonhtmlcommon::breadcrumbs(); + } - $r->print(< - -The LearningOnline Network with CAPA -BEGINNING - $r->print(< - - -

    Search Catalog

    + $r->print(< -$persistent - +$hidden_fields $closebutton -
    -

    Helpful Message

    + +

    $heading

    +

    +$errormsg +

    -Incorrect search query due to blank entry fields. -You need to fill in the relevant -fields on the search page in order for a query to be -processed. +$revise

    - - -RESULTS +$end_page +ENDPAGE + return; } ###################################################################### @@ -1897,35 +3986,36 @@ RESULTS Output a full html page with an error message. +Inputs: + + $r, the request pointer. + $message, the error message for the user. + $closebutton, the specialized close button needed for groupsearch. + =cut ###################################################################### ###################################################################### sub output_date_error { - my ($r,$message)=@_; + my ($r,$message,$closebutton,$hidden_fields)=@_; # make query information persistent to allow for subsequent revision - my $persistent=&make_persistent(); - + my $start_page = &Apache::loncommon::start_page('Search'); + my $end_page = &Apache::loncommon::end_page(); + my $heading = &mt('Error'); $r->print(< - -The LearningOnline Network with CAPA - - - -

    Search Catalog

    +$start_page
    -$persistent +$hidden_fields +onclick='this.form.submit();' /> $closebutton +

    -

    Helpful Message

    -

    +

    $heading

    +

    $message

    - - +$end_page RESULTS } @@ -1936,7 +4026,7 @@ RESULTS =item &start_fresh_session() -Cleans the global %hash by removing all fields which begin with +Cleans the global %groupsearch_db by removing all fields which begin with 'pre_' or 'store'. =cut @@ -1944,64 +4034,29 @@ Cleans the global %hash by removing all ###################################################################### ###################################################################### sub start_fresh_session { - delete $hash{'mode_catalog'}; - foreach (keys %hash) { + delete $groupsearch_db{'mode_catalog'}; + foreach (keys(%groupsearch_db)) { if ($_ =~ /^pre_/) { - delete $hash{$_}; + delete $groupsearch_db{$_}; } if ($_ =~ /^store/) { - delete $hash{$_}; + delete $groupsearch_db{$_}; } } } -###################################################################### -###################################################################### - -=pod - -=item &popwin_js() send javascript to popwin - -=cut +1; -###################################################################### -###################################################################### -sub popwin_js { - # Print javascript out to popwin, but make sure we dont generate - # any javascript errors in doing so. - my ($r,$text) = @_; - $r->print(<<"END"); - -END - $r->rflush(); + &Apache::lonmysql::disconnect_from_db(); + return OK; } -###################################################################### -###################################################################### - -=pod - -=item &popwin_imgupdate() - -Send a given image (and its location) out to the browser. Takes as -input $r, loncapa server id, and an icon URL. - -=cut - -###################################################################### -###################################################################### -sub popwin_imgupdate { - my ($r,$server,$icon) = @_; - &popwin_js($r,'popwin.document.img_'.$Apache::lonnet::hostdom{$server}. - '_'.$server.'.'.'src="/adm/lonIcons/'.$icon.'";'); -} - -1; - __END__ =pod