Diff for /loncom/interface/lonsearchcat.pm between versions 1.161 and 1.199

version 1.161, 2002/11/22 18:36:07 version 1.199, 2003/12/28 20:12:59
Line 59  search (on a server basis) is displayed Line 59  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;  package Apache::lonsearchcat;
   
 # ------------------------------------------------- modules used by this module  
 use strict;  use strict;
 use Apache::Constants qw(:common);  use Apache::Constants qw(:common :http);
 use Apache::lonnet();  use Apache::lonnet();
 use Apache::File();  use Apache::File();
 use CGI qw(:standard);  use CGI qw(:standard);
 use Text::Query;  use Text::Query;
 use DBI;  
 use GDBM_File;  use GDBM_File;
 use Apache::loncommon();  use Apache::loncommon();
 use Apache::lonmysql();  use Apache::lonmysql();
   use Apache::lonlocal;
 # ---------------------------------------- variables used throughout the module  
   
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
   ##
 =pod   ## Global variables
   ##
 =item Global variables  
   
 =over 4  
   
 =item $importbutton  
   
 button to take the select results and go to group sorting  
   
 =item %groupsearch_db     
   
 Database hash used to save values for the groupsearch RAT interface.  
   
 =item $diropendb   
   
 The full path to the (temporary) search database file.  This is set and  
 used in &handler() and is also used in &output_results().  
   
 =item %Views  
   
 Hash which associates an output view description with the function  
 that produces it.  Adding a new view type should be as easy as  
 adding a line to the definition of this hash and making sure the function  
 takes the proper parameters.  
   
 =item $bodytag  
   
 LON-CAPA standard body tag, gotten from &Apache::lonnet::bodytag.  
 No title, no table, just a <body> tag.  
   
 =back   
   
 =cut  
   
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
   my %groupsearch_db;  # Database hash used to save values for the 
 # -- dynamically rendered interface components                       # groupsearch RAT interface.
 my $importbutton; # button to take the selected results and go to group sorting  my %persistent_db;   # gdbm hash which holds data which is supposed to
                        # persist across calls to lonsearchcat.pm
 # -- miscellaneous variables  ## %Views:
 my %groupsearch_db;     # database hash  ## Hash which associates an output view description with the function
 my $diropendb = "";    # db file  ## that produces it.
 #             View Description           Function Pointer  #             View Description/Name      Function Pointer
 my %Views = ("Detailed Citation View" => \&detailed_citation_view,  my %Views = ("Detailed Citation View" => \&detailed_citation_view,
              "Summary View"           => \&summary_view,               "Summary View"           => \&summary_view,
              "Fielded Format"         => \&fielded_format_view,               "Fielded Format"         => \&fielded_format_view,
              "XML/SGML"               => \&xml_sgml_view,               "XML/SGML"               => \&xml_sgml_view,
              "Compact View"           => \&compact_view);               "Compact View"           => \&compact_view);
 my %persistent_db;  
 my $hidden_fields;  
 my $bodytag;  
   
 ######################################################################  
 ######################################################################  
   
 =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  
   
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
 sub handler {  sub handler {
     my $r = shift;      my $r = shift;
   #    &set_defaults();
       #
       # set form defaults
     #      #
       my $hidden_fields;# Hold all the hidden fields used to keep track
                         # of the search system state
       my $importbutton; # button to take the selected results and go to group 
                         # sorting
       my $diropendb;    # The full path to the (temporary) search database file.
                         # This is set and used in &handler() and is also used in 
                         # &output_results().
       my $bodytag;  # LON-CAPA standard body tag, gotten from 
                     # &Apache::lonnet::bodytag. 
                     # No title, no table, just a <body> tag.
   
     my $loaderror=&Apache::lonnet::overloaderror($r);      my $loaderror=&Apache::lonnet::overloaderror($r);
     if ($loaderror) { return $loaderror; }      if ($loaderror) { return $loaderror; }
Line 179  sub handler { Line 120  sub handler {
                       # This button is different for the RAT compared to                        # This button is different for the RAT compared to
                       # normal invocation.                        # normal invocation.
     #      #
     $r->content_type('text/html');      &Apache::loncommon::content_type($r,'text/html');
     $r->send_http_header;      $r->send_http_header;
     return OK if $r->header_only;      return OK if $r->header_only;
     ##      ##
Line 192  sub handler { Line 133  sub handler {
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
              ['catalogmode','launch','acts','mode','form','element','pause',               ['catalogmode','launch','acts','mode','form','element','pause',
               'phase','persistent_db_id','table','start','show',                'phase','persistent_db_id','table','start','show',
               'cleargroupsort']);                'cleargroupsort','titleelement']);
     ##      ##
     ## The following is a trick - we wait a few seconds if asked to so      ## The following is a trick - we wait a few seconds if asked to so
     ##     the daemon running the search can get ahead of the daemon      ##     the daemon running the search can get ahead of the daemon
Line 200  sub handler { Line 141  sub handler {
     ##     this once, so the pause indicator is deleted      ##     this once, so the pause indicator is deleted
     ##      ##
     if (exists($ENV{'form.pause'})) {      if (exists($ENV{'form.pause'})) {
         sleep(3);          sleep(1);
         delete($ENV{'form.pause'});          delete($ENV{'form.pause'});
     }      }
     ##      ##
     ## Initialize global variables      ## Initialize global variables
     ##      ##
     my $domain  = $r->dir_config('lonDefDomain');      my $domain  = $r->dir_config('lonDefDomain');
     $diropendb= "/home/httpd/perl/tmp/".&Apache::lonnet::escape($domain).      $diropendb= "/home/httpd/perl/tmp/$ENV{'user.domain'}_$ENV{'user.name'}_searchcat.db";
             "\_".&Apache::lonnet::escape($ENV{'user.name'})."_searchcat.db";  
     #      #
     # set the name of the persistent database      # set the name of the persistent database
     #          $ENV{'form.persistent_db_id'} can only have digits in it.      #          $ENV{'form.persistent_db_id'} can only have digits in it.
Line 275  END Line 215  END
         $hidden_fields .= '<input type="hidden" name="element" value="'.          $hidden_fields .= '<input type="hidden" name="element" value="'.
                 $ENV{'form.element'}.'" />'."\n";                  $ENV{'form.element'}.'" />'."\n";
     }      }
       if (exists($ENV{'form.titleelement'})) {
           $hidden_fields .= '<input type="hidden" name="titleelement" value="'.
                   $ENV{'form.titleelement'}.'" />'."\n";
       }
     if (exists($ENV{'form.mode'})) {      if (exists($ENV{'form.mode'})) {
         $hidden_fields .= '<input type="hidden" name="mode" value="'.          $hidden_fields .= '<input type="hidden" name="mode" value="'.
                 $ENV{'form.mode'}.'" />'."\n";                  $ENV{'form.mode'}.'" />'."\n";
Line 323  END Line 267  END
     ## Switch on the phase      ## Switch on the phase
     ##      ##
     if ($ENV{'form.phase'} eq 'disp_basic') {      if ($ENV{'form.phase'} eq 'disp_basic') {
         &print_basic_search_form($r,$closebutton);          &print_basic_search_form($r,$closebutton,$hidden_fields);
     } elsif ($ENV{'form.phase'} eq 'disp_adv') {      } elsif ($ENV{'form.phase'} eq 'disp_adv') {
         &print_advanced_search_form($r,$closebutton);          &print_advanced_search_form($r,$closebutton,$hidden_fields);
     } elsif ($ENV{'form.phase'} eq 'results') {      } elsif ($ENV{'form.phase'} eq 'results') {
         &display_results($r,$importbutton,$closebutton);          &display_results($r,$importbutton,$closebutton,$diropendb);
     } elsif ($ENV{'form.phase'} =~ /^(sort|run_search)$/) {      } elsif ($ENV{'form.phase'} =~ /^(sort|run_search)$/) {
         my ($query,$customquery,$customshow,$libraries,$pretty_string) =          my ($query,$customquery,$customshow,$libraries,$pretty_string) =
             &get_persistent_data($persistent_db_file,              &get_persistent_data($persistent_db_file,
Line 339  END Line 283  END
             &run_search($r,$query,$customquery,$customshow,              &run_search($r,$query,$customquery,$customshow,
                         $libraries,$pretty_string);                          $libraries,$pretty_string);
         }          }
       } elsif ($ENV{'form.phase'} eq 'course_search') {
           &course_search($r);
     } elsif(($ENV{'form.phase'} eq 'basic_search') ||      } elsif(($ENV{'form.phase'} eq 'basic_search') ||
             ($ENV{'form.phase'} eq 'adv_search')) {              ($ENV{'form.phase'} eq 'adv_search')) {
         $ENV{'form.searchmode'} = 'basic';          $ENV{'form.searchmode'} = 'basic';
Line 347  END Line 293  END
         }          }
         # Set up table          # Set up table
         if (! defined(&create_results_table())) {          if (! defined(&create_results_table())) {
       my $errorstring=&Apache::lonmysql::get_error();
             $r->print(<<END);              $r->print(<<END);
 <html><head><title>Search Error</title></head>  <html><head><title>Search Error</title></head>
 $bodytag  $bodytag
 Unable to create table in which to store search results.    Unable to create table in which to store search results.  
 The search has been aborted.  The search has been aborted.
   <br />$errorstring
 </body>  </body>
 </html>  </html>
 END  END
Line 374  END Line 322  END
             (undef,undef,undef,undef);              (undef,undef,undef,undef);
         my $pretty_string;          my $pretty_string;
         if ($ENV{'form.phase'} eq 'basic_search') {          if ($ENV{'form.phase'} eq 'basic_search') {
             ($query,$pretty_string) = &parse_basic_search($r,$closebutton);              ($query,$pretty_string,$libraries) = 
                   &parse_basic_search($r,$closebutton,$hidden_fields);
         } else {                      # Advanced search          } else {                      # Advanced search
             ($query,$customquery,$customshow,$libraries,$pretty_string)               ($query,$customquery,$customshow,$libraries,$pretty_string) 
                 = &parse_advanced_search($r,$closebutton);                  = &parse_advanced_search($r,$closebutton,$hidden_fields);
             return OK if (! defined($query));              return OK if (! defined($query));
         }          }
         &make_persistent({ query => $query,          &make_persistent({ query => $query,
Line 396  END Line 345  END
   
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
   ##
   ##   Course Search
   ##
   ######################################################################
   ######################################################################
   {   # Scope the course search to avoid global variables
   #
   # Variables For course search
   my %alreadyseen;
   my %hash;
   my $totalfound;
   
   sub course_search {
       my $r=shift;
       my $bodytag=&Apache::loncommon::bodytag('Course Search');
       my $pretty_search_string = '<b>'.$ENV{'form.courseexp'}.'</b>';
       my $search_string = $ENV{'form.courseexp'};
       my @New_Words;
       if ($ENV{'form.crsrelated'}) {
           ($search_string,@New_Words) = &related_version($ENV{'form.courseexp'});
           if (@New_Words) {
               $pretty_search_string .= " with related words: <b>@New_Words</b>.";
           } else {
               $pretty_search_string .= " with no related words.";
           }
       }
       my $fulltext=$ENV{'form.crsfulltext'};
       my @allwords=($search_string,@New_Words);
       $totalfound=0;
       $r->print('<html><head><title>LON-CAPA Course Search</title></head>'.
         $bodytag.$pretty_search_string);
       $r->rflush();
   # ======================================================= Go through the course
       undef %alreadyseen;
       %alreadyseen=();
       my $c=$r->connection;
       if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.".db",
               &GDBM_READER(),0640)) {
           foreach (keys %hash) {
               if ($c->aborted()) { last; }
               if (($_=~/^src\_(.+)$/) && (!$alreadyseen{$hash{$_}})) {
                   &checkonthis($r,$hash{$_},0,$hash{'title_'.$1},$fulltext,
                                @allwords);
               }
           }
           untie(%hash);
       }
       unless ($totalfound) {
    $r->print('<p>'.&mt('No resources found').'.</p>');
       }
   # =================================================== Done going through course
       $r->print('</body></html>');
   }
   
   # =============================== This pulls up a resource and its dependencies
   
   sub checkonthis {
       my ($r,$url,$level,$title,$fulltext,@allwords)=@_;
       $alreadyseen{$url}=1;
       $r->rflush();
       my $result=&Apache::lonnet::metadata($url,'title').' '.
                  &Apache::lonnet::metadata($url,'subject').' '.
                  &Apache::lonnet::metadata($url,'abstract').' '.
                  &Apache::lonnet::metadata($url,'keywords');
       if (($url) && ($fulltext)) {
    $result.=&Apache::lonnet::ssi_body($url);
       }
       $result=~s/\s+/ /gs;
       my $applies=0;
       foreach (@allwords) {
           if ($_=~/\w/) {
      if ($result=~/$_/si) {
         $applies++;
              }
          }
       }
   # Does this resource apply?
       if ($applies) {
          $r->print('<br />');
          for (my $i=0;$i<=$level*5;$i++) {
              $r->print('&nbsp;');
          }
          $r->print('<a href="'.$url.'" target="cat">'.
    ($title?$title:$url).'</a><br />');
          $totalfound++;
       } elsif ($fulltext) {
          $r->print(' .');
       }
       $r->rflush();
   # Check also the dependencies of this one
       my $dependencies=
                   &Apache::lonnet::metadata($url,'dependencies');
       foreach (split(/\,/,$dependencies)) {
          if (($_=~/^\/res\//) && (!$alreadyseen{$_})) {
             &checkonthis($r,$_,$level+1,'',$fulltext,@allwords);
          }
       }
   }
   
   sub untiehash {
       if (tied(%hash)) {
           untie(%hash);
       }
   }
   
   } # End of course search scoping
   
   ######################################################################
   ######################################################################
   
 =pod   =pod 
   
Line 409  Returns a scalar which holds html for th Line 467  Returns a scalar which holds html for th
 ######################################################################  ######################################################################
   
 sub print_basic_search_form{  sub print_basic_search_form{
     my ($r,$closebutton) = @_;      my ($r,$closebutton,$hidden_fields) = @_;
     my $bodytag=&Apache::loncommon::bodytag('Catalog Search');      my $bodytag=&Apache::loncommon::bodytag('Search');
     my $scrout=<<"ENDDOCUMENT";      my $scrout=<<"ENDDOCUMENT";
 <html>  <html>
 <head>  <head>
Line 424  sub print_basic_search_form{ Line 482  sub print_basic_search_form{
 </script>  </script>
 </head>  </head>
 $bodytag  $bodytag
 <form method="post" action="/adm/searchcat">  ENDDOCUMENT
   if (&Apache::lonnet::allowed('bre',$ENV{'request.role.domain'})) {
       my $CatalogSearch=&mt('Catalog Search');
       my $Statement=&mt('Enter terms or phrases separated by AND, OR, or NOT then press SEARCH below');
       $scrout.=(<<ENDDOCUMENT);
   <h1>$CatalogSearch</h1>
   <form name="loncapa_search" method="post" action="/adm/searchcat">
 <input type="hidden" name="phase" value="basic_search" />  <input type="hidden" name="phase" value="basic_search" />
 $hidden_fields  $hidden_fields
 <p>  <p>
 Enter terms or phrases separated by AND, OR, or NOT   $Statement.
 then press SEARCH below.  
 </p>  </p>
 <p>  <p>
 <table>  <table>
Line 437  then press SEARCH below. Line 500  then press SEARCH below.
 ENDDOCUMENT  ENDDOCUMENT
     $scrout.='&nbsp;'.&simpletextfield('basicexp',$ENV{'form.basicexp'},40).      $scrout.='&nbsp;'.&simpletextfield('basicexp',$ENV{'form.basicexp'},40).
         '&nbsp;';          '&nbsp;';
     my $checkbox = &simplecheckbox('related',$ENV{'form.related'});      my $relatedcheckbox = &simplecheckbox('related','related',$ENV{'form.related'});
       my $domain = $r->dir_config('lonDefDomain');
       my $domaincheckbox = &simplecheckbox('domains',$domain);
       my $srch=&mt('Search');
       my $header=&mt('Advanced Search');
       my $userelatedwords=&mt('use related words');
       my $onlysearchdomain=&mt('only search domain');
     $scrout.=<<END;      $scrout.=<<END;
 </td><td><a  </td><td><a
 href="/adm/searchcat?phase=disp_adv&catalogmode=$ENV{'form.catalogmode'}&launch=$ENV{'form.launch'}"  href="/adm/searchcat?phase=disp_adv&catalogmode=$ENV{'form.catalogmode'}&launch=$ENV{'form.launch'}&mode=$ENV{'form.mode'}"
 >Advanced Search</a></td></tr>  >$header</a></td></tr>
 <tr><td>$checkbox use related words</td><td></td></tr>  <tr><td>$relatedcheckbox $userelatedwords</td>
       <td>$domaincheckbox $onlysearchdomain <b>$domain</b></td></tr>
 </table>  </table>
 </p>  </p>
 <p>  <p>
 &nbsp;<input type="submit" name="basicsubmit" value='SEARCH' />&nbsp;  &nbsp;<input type="submit" name="basicsubmit" value='$srch' />&nbsp;
 $closebutton  $closebutton
 END  END
     $scrout.=&selectbox(undef,'viewselect',      $scrout.=&selectbox('View','viewselect',
  $ENV{'form.viewselect'},   $ENV{'form.viewselect'},
  undef,undef,undef,   undef,undef,undef,
  sort(keys(%Views)));   sort(keys(%Views)));
     $scrout.=&selectbox(undef,'show',      $scrout.=&selectbox('Per Page','show',
  $ENV{'form.show'},   $ENV{'form.show'},
  undef,undef,undef,   undef,undef,undef,
  (10,20,50,100));   (10,20,50,100));
     $scrout.=<<ENDDOCUMENT;      $scrout.=<<ENDDOCUMENT;
 per page.  
 </p>  </p>
 </form>  </form>
   ENDDOCUMENT
       }
       if ($ENV{'request.course.id'}) {
    my %lt=&Apache::lonlocal::texthash(
      'srch' => 'Search',
                                              'header' => 'Course Search',
    'note' => 'Enter terms or phrases, then press "Search" below',
      );
           $scrout.=(<<ENDCOURSESEARCH);
   <hr />
   <h1>$lt{'header'}</h1>    
   <form name="course_search" method="post" action="/adm/searchcat">
   <input type="hidden" name="phase" value="course_search" />
   $hidden_fields
   <p>
   $lt{'note'}.
   </p>
   <p>
   <table>
   <tr><td>
   ENDCOURSESEARCH
           $scrout.='&nbsp;'.
               &simpletextfield('courseexp',$ENV{'form.courseexp'},40);
           my $crscheckbox = 
               &simplecheckbox('crsfulltext',$ENV{'form.crsfulltext'});
           my $relcheckbox = 
               &simplecheckbox('crsrelated',$ENV{'form.crsrelated'});
           $scrout.=(<<ENDENDCOURSE);
   </td></tr>
   <tr><td>$relcheckbox use related words</td><td></td></tr>
   <tr><td>$crscheckbox fulltext search (time consuming)</td><td></td></tr>
   </table><p>
   &nbsp;<input type="submit" name="coursesubmit" value='$lt{'srch'}' />
   </p>
   ENDENDCOURSE
       }
       $scrout.=(<<ENDDOCUMENT);
 </body>  </body>
 </html>  </html>
 ENDDOCUMENT  ENDDOCUMENT
Line 482  Returns a scalar which holds html for th Line 588  Returns a scalar which holds html for th
 ######################################################################  ######################################################################
   
 sub print_advanced_search_form{  sub print_advanced_search_form{
     my ($r,$closebutton) = @_;      my ($r,$closebutton,$hidden_fields) = @_;
     my $advanced_buttons = <<"END";      my $advanced_buttons = <<"END";
 <p>  <p>
 <input type="submit" name="advancedsubmit" value='SEARCH' />  <input type="submit" name="advancedsubmit" value='SEARCH' />
Line 528  ENDHEADER Line 634  ENDHEADER
  undef,undef,undef,   undef,undef,undef,
  (10,20,50,100));   (10,20,50,100));
     $scrout.='&nbsp;'.      $scrout.='&nbsp;'.
         '<font color="#800000" face="helvetica">Per Page</font>';          '<font color="#800000" face="helvetica">'.&mt('Per Page').'</font>';
     $scrout.="</td><td>Related<br />Words</td></tr>\n";      $scrout.="</td><td>".&mt('Related').'<br />'.&mt('Words')."</td></tr>\n";
     $scrout.=&searchphrasefield_with_related('title',   'title'   ,      $scrout.=&searchphrasefield_with_related('title',   'title'   ,
                                              $ENV{'form.title'});                                               $ENV{'form.title'});
     $scrout.=&searchphrasefield('author',  'author'  ,$ENV{'form.author'});      $scrout.=&searchphrasefield('author',  'author'  ,$ENV{'form.author'});
Line 542  ENDHEADER Line 648  ENDHEADER
                                              $ENV{'form.notes'});                                               $ENV{'form.notes'});
     $scrout.=&searchphrasefield_with_related('abstract','abstract',      $scrout.=&searchphrasefield_with_related('abstract','abstract',
                                              $ENV{'form.abstract'});                                               $ENV{'form.abstract'});
       $scrout.=&searchphrasefield('Standards','standards',$ENV{'form.standards'});
     # Hack - an empty table row.      # Hack - an empty table row.
     $scrout.="<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>\n";      $scrout.="<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>\n";
     $scrout.=&searchphrasefield('file<br />extension','extension',      $scrout.=&searchphrasefield('file<br />extension','extension',
Line 571  ENDHEADER Line 678  ENDHEADER
     my @domains =&Apache::loncommon::get_domains();      my @domains =&Apache::loncommon::get_domains();
     # adjust the size of the select box      # adjust the size of the select box
     my $size = 4;      my $size = 4;
     my $size = (scalar @domains < ($size - 1) ? scalar @domains + 1 : $size);      $size = (scalar @domains < ($size - 1) ? scalar @domains + 1 : $size);
     $scrout.="\n".'<font color="#800000" face="helvetica"><b>'.      $scrout.="\n".'<font color="#800000" face="helvetica"><b>'.
         'DOMAINS</b></font><br />'.          'DOMAINS TO BE SEARCHED</b></font><br />'.
             '<select name="domains" size="'.$size.'" multiple>'."\n".              '<select name="domains" size="'.$size.'" multiple>'."\n".
                 '<option name="any" value="any" '.                  '<option name="any" value="any" '.
                     ($domain_hash{'any'}? 'selected ' :'').                      ($domain_hash{'any'}? 'selected ' :'').
Line 586  ENDHEADER Line 693  ENDHEADER
     #----------------------------------------------------------------      #----------------------------------------------------------------
     $scrout.=&selectbox('Limit by language','language',      $scrout.=&selectbox('Limit by language','language',
  $ENV{'form.language'},'any','Any Language',   $ENV{'form.language'},'any','Any Language',
  \&{Apache::loncommon::languagedescription},   \&Apache::loncommon::languagedescription,
  (&Apache::loncommon::languageids),   (&Apache::loncommon::languageids),
  );   );
 # ------------------------------------------------ Compute date selection boxes  # ------------------------------------------------ Compute date selection boxes
Line 633  LASTREVISIONDATEEND Line 740  LASTREVISIONDATEEND
     $scrout.=&selectbox('Limit by copyright/distribution','copyright',      $scrout.=&selectbox('Limit by copyright/distribution','copyright',
  $ENV{'form.copyright'},   $ENV{'form.copyright'},
  'any','Any copyright/distribution',   'any','Any copyright/distribution',
  \&{Apache::loncommon::copyrightdescription},   \&Apache::loncommon::copyrightdescription,
  (&Apache::loncommon::copyrightids),   (&Apache::loncommon::copyrightids),
  );   );
 # ------------------------------------------- Compute customized metadata field  # ------------------------------------------- Compute customized metadata field
Line 699  sub get_persistent_form_data { Line 806  sub get_persistent_form_data {
     # Loop through the keys, looking for 'form.'      # Loop through the keys, looking for 'form.'
     foreach my $name (keys(%persistent_db)) {      foreach my $name (keys(%persistent_db)) {
         next if ($name !~ /^form./);          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}));          next if (exists($ENV{$name}));
         my @values = map {           my @values = map { 
             &Apache::lonnet::unescape($_);              &Apache::lonnet::unescape($_);
Line 713  sub get_persistent_form_data { Line 827  sub get_persistent_form_data {
     untie (%persistent_db);      untie (%persistent_db);
     return 1;      return 1;
 }  }
   
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
   
Line 861  sub simpletextfield { Line 976  sub simpletextfield {
   
 =item &simplecheckbox()  =item &simplecheckbox()
   
 Inputs: $name,$value  Inputs: $name,$value,$checked
   
 Returns a simple check box with the given $name.  Returns a simple check box with the given $name.
 If $value eq 'on' the box is checked.  If $value eq 'on' the box is checked.
Line 871  If $value eq 'on' the box is checked. Line 986  If $value eq 'on' the box is checked.
 ###############################################  ###############################################
 ###############################################  ###############################################
   
 sub simplecheckbox {  sub simplecheckbox{
     my ($name,$value)=@_;      my ($name,$value,$checked)=@_;
     my $checked='';      $checked="checked" if ($value eq $checked || $value eq 'on');
     $checked="checked" if $value eq 'on';      return '<input type="checkbox" name="'.$name.'" value="'.$value.'" '.
     return '<input type="checkbox" name="'.$name.'" '. $checked . ' />';          $checked.' />';
 }  }
   
 ###############################################  ###############################################
Line 896  field heading. Line 1011  field heading.
 ###############################################  ###############################################
   
 sub fieldtitle {  sub fieldtitle {
     my $title = uc(shift());      my $title = uc(&mt(shift()));
     return '<font color="#800000" face="helvetica"><b>'.$title.      return '<font color="#800000" face="helvetica"><b>'.$title.
         ':&nbsp;</b></font>';          ':&nbsp;</b></font>';
 }  }
Line 991  END Line 1106  END
     my $i = 1;      my $i = 1;
     foreach (qw/January February March April May June       foreach (qw/January February March April May June 
      July August September October November December /){       July August September October November December /){
  $month .="<option value=\"$i\">$_</option>\n";   $month .="<option value=\"$i\">".&mt($_)."</option>\n";
  $i++;   $i++;
     }      }
     $month.="</select>\n";      $month.="</select>\n";
Line 1068  sub selectbox { Line 1183  sub selectbox {
     my ($title,$name,$default,$anyvalue,$anytag,$functionref,@idlist)=@_;      my ($title,$name,$default,$anyvalue,$anytag,$functionref,@idlist)=@_;
     if (! defined($functionref)) { $functionref = sub { $_[0]}; }      if (! defined($functionref)) { $functionref = sub { $_[0]}; }
     my $selout='';      my $selout='';
       $title=&mt($title);
     if (defined($title)) {      if (defined($title)) {
         my $uctitle=uc($title);          my $uctitle=uc($title);
         $selout="\n".'<p><font color="#800000" face="helvetica">'.          $selout="\n".'<p><font color="#800000" face="helvetica">'.
Line 1078  sub selectbox { Line 1194  sub selectbox {
     foreach (@idlist) {      foreach (@idlist) {
         $selout.='<option value="'.$_.'"';          $selout.='<option value="'.$_.'"';
         if ($_ eq $default and !/^any$/) {          if ($_ eq $default and !/^any$/) {
     $selout.=' selected >'.&{$functionref}($_).'</option>';      $selout.=' selected >'.&mt(&{$functionref}($_)).'</option>';
  }   }
  elsif ($_ eq $default and /^$anyvalue$/) {   elsif ($_ eq $default and /^$anyvalue$/) {
     $selout.=' selected >'.$anytag.'</option>';      $selout.=' selected >'.&mt($anytag).'</option>';
  }   }
         else {$selout.='>'.&{$functionref}($_).'</option>';}          else {$selout.='>'.&mt(&{$functionref}($_)).'</option>';}
     }      }
     return $selout.'</select>'.(defined($title)?'</p>':' ');      return $selout.'</select>'.(defined($title)?'</p>':' ');
 }  }
Line 1125  Parse advanced search form and return th Line 1241  Parse advanced search form and return th
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
 sub parse_advanced_search {  sub parse_advanced_search {
     my ($r,$closebutton)=@_;      my ($r,$closebutton,$hidden_fields)=@_;
     my $fillflag=0;      my $fillflag=0;
     my $pretty_search_string = "<br />\n";      my $pretty_search_string = "<br />\n";
     # Clean up fields for safety      # Clean up fields for safety
Line 1159  sub parse_advanced_search { Line 1275  sub parse_advanced_search {
  }   }
     }      }
     unless ($fillflag) {      unless ($fillflag) {
  &output_blank_field_error($r,$closebutton,'phase=disp_adv');   &output_blank_field_error($r,$closebutton,'phase=disp_adv',$hidden_fields);
  return ;   return ;
     }      }
     # Turn the form input into a SQL-based query      # Turn the form input into a SQL-based query
Line 1242  sub parse_advanced_search { Line 1358  sub parse_advanced_search {
  );   );
     # Test to see if date windows are legitimate      # Test to see if date windows are legitimate
     if ($datequery=~/^Incorrect/) {      if ($datequery=~/^Incorrect/) {
  &output_date_error($r,$datequery,$closebutton);   &output_date_error($r,$datequery,$closebutton,$hidden_fields);
  return ;   return ;
     } elsif ($datequery) {      } elsif ($datequery) {
         # Here is where you would set up pretty_search_string to output          # Here is where you would set up pretty_search_string to output
Line 1269  sub parse_advanced_search { Line 1385  sub parse_advanced_search {
     ## ---------------------------------------------------------------      ## ---------------------------------------------------------------
     ## Deal with restrictions to given domains      ## Deal with restrictions to given domains
     ##       ## 
       my ($libraries_to_query,$pretty_domains_string) = 
           &parse_domain_restrictions();
       $pretty_search_string .= $pretty_domains_string."<br />\n";
       #
       if (@queries) {
    $query=join(" AND ",@queries);
    $query="select * from metadata where $query";
       } elsif ($customquery) {
           $query = '';
       }
       return ($query,$customquery,$customshow,$libraries_to_query,
               $pretty_search_string);
   }
   
   sub parse_domain_restrictions {
     my $libraries_to_query = undef;      my $libraries_to_query = undef;
     # $ENV{'form.domains'} can be either a scalar or an array reference.      # $ENV{'form.domains'} can be either a scalar or an array reference.
     # We need an array.      # We need an array.
     my @allowed_domains = (ref($ENV{'form.domains'}) ? @{$ENV{'form.domains'}}       if (! exists($ENV{'form.domains'})) {
                            :  ($ENV{'form.domains'}) );          return (undef,'');
       }
       my @allowed_domains;
       if (ref($ENV{'form.domains'})) {
           @allowed_domains =  @{$ENV{'form.domains'}};
       } else {
           @allowed_domains = ($ENV{'form.domains'});
       }
     my %domain_hash = ();      my %domain_hash = ();
     my $pretty_domains_string;      my $pretty_domains_string;
     foreach (@allowed_domains) {      foreach (@allowed_domains) {
Line 1296  sub parse_advanced_search { Line 1434  sub parse_advanced_search {
             }              }
         }          }
     }      }
     $pretty_search_string .= $pretty_domains_string."<br />\n";      return ($libraries_to_query,$pretty_domains_string);
     #  
     if (@queries) {  
  $query=join(" AND ",@queries);  
  $query="select * from metadata where $query";  
     } elsif ($customquery) {  
         $query = '';  
     }  
     return ($query,$customquery,$customshow,$libraries_to_query,  
             $pretty_search_string);  
 }  }
   
 ######################################################################  ######################################################################
Line 1333  sub parse_basic_search { Line 1462  sub parse_basic_search {
  $ENV{"form.$_"}=&Apache::lonnet::unescape($ENV{"form.$_"});   $ENV{"form.$_"}=&Apache::lonnet::unescape($ENV{"form.$_"});
  $ENV{"form.$_"}=~s/[^\w\/\s\(\)\=\-\"\']//g;   $ENV{"form.$_"}=~s/[^\w\/\s\(\)\=\-\"\']//g;
     }      }
       my ($libraries_to_query,$pretty_domains_string) = 
           &parse_domain_restrictions();
     # Check to see if enough is filled in      # Check to see if enough is filled in
     unless (&filled($ENV{'form.basicexp'})) {      unless (&filled($ENV{'form.basicexp'})) {
  &output_blank_field_error($r,$closebutton,'phase=disp_basic');   &output_blank_field_error($r,$closebutton,'phase=disp_basic');
Line 1352  sub parse_basic_search { Line 1482  sub parse_basic_search {
     }      }
     # Build SQL query string based on form page      # Build SQL query string based on form page
     my $query='';      my $query='';
     my $concatarg=join(',"    ",',      my $concatarg=join(',',
        ('title', 'author', 'subject', 'notes', 'abstract',         ('title', 'author', 'subject', 'notes', 'abstract',
                         'keywords'));                          'keywords'));
     $concatarg='title' if $ENV{'form.titleonly'};      $concatarg='title' if $ENV{'form.titleonly'};
     $query=&build_SQL_query('concat('.$concatarg.')',$search_string);      $query=&build_SQL_query('concat_ws(" ",'.$concatarg.')',$search_string);
       if (defined($pretty_domains_string) && $pretty_domains_string ne '') {
           $pretty_search_string .= ' '.$pretty_domains_string;
       }
     $pretty_search_string .= "<br />\n";      $pretty_search_string .= "<br />\n";
     return 'select * from metadata where '.$query,$pretty_search_string;      my $final_query = 'SELECT * FROM metadata WHERE '.$query;
   #    &Apache::lonnet::logthis($final_query);
       return ($final_query,$pretty_search_string,
               $libraries_to_query);
 }  }
   
   
Line 1471  sub recursive_SQL_query_build { Line 1607  sub recursive_SQL_query_build {
     my @matches=($pattern=~/(\[[^\]|\[]*\])/g);      my @matches=($pattern=~/(\[[^\]|\[]*\])/g);
     return $pattern unless @matches;      return $pattern unless @matches;
     foreach my $match (@matches) {      foreach my $match (@matches) {
  $match=~/\[ (\w+)\s(.*) \]/;          $match=~/\[ (\w+)\s(.*) \]/;
  my ($key,$value)=($1,$2);          my ($key,$value)=($1,$2);
  my $replacement='';          my $replacement='';
  if ($key eq 'literal') {          if ($key eq 'literal') {
     $replacement="($dkey like \"\%$value\%\")";              $replacement="($dkey LIKE \"\%$value\%\")";
  }          } elsif (lc($key) eq 'not') {
  elsif ($key eq 'not') {              $value=~s/LIKE/NOT LIKE/;
     $value=~s/like/not like/;  #          $replacement="($dkey not like $value)";
 #    $replacement="($dkey not like $value)";              $replacement="$value";
     $replacement="$value";          } elsif ($key eq 'and') {
  }              $value=~/(.*[\"|\)]) ([|\(|\^].*)/;
  elsif ($key eq 'and') {              $replacement="($1 AND $2)";
     $value=~/(.*[\"|\)]) ([|\(|\^].*)/;   } elsif ($key eq 'or') {
     $replacement="($1 AND $2)";              $value=~/(.*[\"|\)]) ([|\(|\^].*)/;
  }              $replacement="($1 OR $2)";
  elsif ($key eq 'or') {  
     $value=~/(.*[\"|\)]) ([|\(|\^].*)/;  
     $replacement="($1 OR $2)";  
  }   }
  substr($pattern,   substr($pattern,
        index($pattern,$match),                 index($pattern,$match),
        length($match),                 length($match),
        $replacement                 $replacement);
        );  
     }      }
     &recursive_SQL_query_build($dkey,$pattern);      &recursive_SQL_query_build($dkey,$pattern);
 }  }
Line 1661  sub ensure_db_and_table { Line 1793  sub ensure_db_and_table {
 ######################################################################  ######################################################################
 sub print_sort_form {  sub print_sort_form {
     my ($r,$pretty_query_string) = @_;      my ($r,$pretty_query_string) = @_;
       my $bodytag=&Apache::loncommon::bodytag(undef,undef,undef,1);
     ##      ##
     my %SortableFields =       my %SortableFields=&Apache::lonlocal::texthash( 
         (id        => 'Default',           id        => 'Default',
          title     => 'Title',           title     => 'Title',
          author    => 'Author',           author    => 'Author',
          subject   => 'Subject',           subject   => 'Subject',
Line 1675  sub print_sort_form { Line 1808  sub print_sort_form {
          copyright => 'Copyright',           copyright => 'Copyright',
          hostname  => 'Host',           hostname  => 'Host',
          creationdate     => 'Creation Date',           creationdate     => 'Creation Date',
          lastrevisiondate => 'Revision Date',           lastrevisiondate => 'Revision Date'
      );       );
     ##      ##
     my $table = $ENV{'form.table'};      my $table = $ENV{'form.table'};
Line 1751  the following format: Line 1884  the following format:
   
 =cut  =cut
   
 ##  #####################################################################
 ## Restrictions:  #####################################################################
 ##    columns of type 'text' and 'blob' cannot have defaults.  
 ##    columns of type 'enum' cannot be used for FULLTEXT.  
 ##  
 my @DataOrder = qw/id title author subject url keywords version notes  
     abstract mime lang owner copyright creationdate lastrevisiondate hostname/;  
   
 my %Datatypes =   my @Datatypes = 
     ( id        =>{ type         => 'MEDIUMINT',      ( { name => 'id', 
                     restrictions => 'UNSIGNED NOT NULL',          type => 'MEDIUMINT',
                     primary_key  => 'yes',          restrictions => 'UNSIGNED NOT NULL',
                     auto_inc     => 'yes'          primary_key  => 'yes',
                     },          auto_inc     => 'yes' },
       title     =>{ type=>'TEXT'},        { name => 'title',     type=>'TEXT'},
       author    =>{ type=>'TEXT'},        { name => 'author',    type=>'TEXT'},
       subject   =>{ type=>'TEXT'},        { name => 'subject',   type=>'TEXT'},
       url       =>{ type=>'TEXT',        { name => 'url',       type=>'TEXT', restrictions => 'NOT NULL' },
                     restrictions => 'NOT NULL' },        { name => 'keywords',  type=>'TEXT'},
       keywords  =>{ type=>'TEXT'},        { name => 'version',   type=>'TEXT'},
       version   =>{ type=>'TEXT'},        { name => 'notes',     type=>'TEXT'},
       notes     =>{ type=>'TEXT'},        { name => 'abstract',  type=>'TEXT'},
       abstract  =>{ type=>'TEXT'},        { name => 'mime',      type=>'TEXT'},
       mime      =>{ type=>'TEXT'},        { name => 'language',  type=>'TEXT'},
       lang      =>{ type=>'TEXT'},        { name => 'owner',     type=>'TEXT'},
       owner     =>{ type=>'TEXT'},        { name => 'copyright', type=>'TEXT'},
       copyright =>{ type=>'TEXT'},        { name => 'dependencies',     type=>'TEXT'},
       hostname  =>{ type=>'TEXT'},        { name => 'modifyinguser', type=>'TEXT'},
         { name => 'authorspace', type=>'TEXT'},
         { name => 'lowestgradelevel',  type=>'INT'},
         { name => 'highestgradelevel', type=>'INT'},
         { name => 'standards', type=>'TEXT'},
         { name => 'count',     type=>'INT'},
         { name => 'course', type=>'INT'},
         { name => 'course_list',  type=>'TEXT'},
         { name => 'goto', type=>'INT'},
         { name => 'goto_list',  type=>'TEXT'},
         { name => 'comefrom', type=>'INT'},
         { name => 'comefrom_list',  type=>'TEXT'},
         { name => 'sequsage', type=>'INT'},
         { name => 'sequsage_list',  type=>'TEXT'},
         { name => 'stdno', type=>'INT'},
         { name => 'stdno_list',  type=>'TEXT'},
         { name => 'avetries', type=>'FLOAT'},
         { name => 'avetries_list',  type=>'TEXT'},
         { name => 'difficulty', type=>'FLOAT'},
         { name => 'difficulty_list',  type=>'TEXT'},
         { name => 'clear',  type=>'FLOAT'},
         { name => 'technical',  type=>'FLOAT'},
         { name => 'correct',  type=>'FLOAT'},
         { name => 'helpful',  type=>'FLOAT'},
         { name => 'depth',  type=>'FLOAT'},
         { name => 'hostname', type=> 'TEXT'},
       #--------------------------------------------------        #--------------------------------------------------
       creationdate     =>{ type=>'DATETIME'},        { name => 'creationdate',     type=>'DATETIME'},
       lastrevisiondate =>{ type=>'DATETIME'},        { name => 'lastrevisiondate', type=>'DATETIME'},
       #--------------------------------------------------        #--------------------------------------------------
       );        );
   
Line 1809  Returns: the identifier of the table on Line 1962  Returns: the identifier of the table on
 ######################################################################  ######################################################################
 sub create_results_table {  sub create_results_table {
     my $table = &Apache::lonmysql::create_table      my $table = &Apache::lonmysql::create_table
         ( { columns => \%Datatypes,          ( { columns => \@Datatypes,
             column_order => \@DataOrder,              FULLTEXT => [{'columns' => \@Fullindicies},],
             fullindex => \@Fullindicies,  
         } );          } );
     if (defined($table)) {      if (defined($table)) {
         $ENV{'form.table'} = $table;          $ENV{'form.table'} = $table;
Line 1913  sub revise_button { Line 2065  sub revise_button {
 ######################################################################  ######################################################################
 sub run_search {  sub run_search {
     my ($r,$query,$customquery,$customshow,$serverlist,$pretty_string) = @_;      my ($r,$query,$customquery,$customshow,$serverlist,$pretty_string) = @_;
       my $bodytag=&Apache::loncommon::bodytag(undef,undef,undef,1);
     my $connection = $r->connection;      my $connection = $r->connection;
     #      #
     # Timing variables      # Timing variables
Line 1936  END Line 2089  END
     if (@Lines > 2) {      if (@Lines > 2) {
         $pretty_string = join '<br \>',(@Lines[0..2],'....<br />');          $pretty_string = join '<br \>',(@Lines[0..2],'....<br />');
     }      }
     $r->print("Search: ".$pretty_string);      $r->print(&mt("Search").": ".$pretty_string);
     $r->rflush();      $r->rflush();
     #      #
     # Determine the servers we need to contact.      # Determine the servers we need to contact.
Line 1995  END Line 2148  END
     my $time_remaining = $max_time - (time - $starttime) ;      my $time_remaining = $max_time - (time - $starttime) ;
     my $last_time = $time_remaining;      my $last_time = $time_remaining;
     &update_seconds($r,$time_remaining);      &update_seconds($r,$time_remaining);
       &update_status($r,'contacting '.$Servers_to_contact[0]);
     while (($time_remaining > 0) &&      while (($time_remaining > 0) &&
            ((@Servers_to_contact) || keys(%Server_status))) {             ((@Servers_to_contact) || keys(%Server_status))) {
         # Send out a search request if it needs to be done.          # Send out a search request if it needs to be done.
         if (@Servers_to_contact) {          if (@Servers_to_contact) {
             # Contact one server              # Contact one server
             my $server = shift(@Servers_to_contact);              my $server = shift(@Servers_to_contact);
               &update_status($r,&mt('contacting').' '.$server);
             my $reply=&Apache::lonnet::metadata_query($query,$customquery,              my $reply=&Apache::lonnet::metadata_query($query,$customquery,
                                                       $customshow,[$server]);                                                        $customshow,[$server]);
             ($server) = keys(%$reply);              ($server) = keys(%$reply);
             $Server_status{$server} = $reply->{$server};              $Server_status{$server} = $reply->{$server};
             &update_status($r,'contacting '.$server);  
         } else {          } else {
             # wait a sec. to give time for files to be written              # wait a sec. to give time for files to be written
             # This sleep statement is here instead of outside the else               # This sleep statement is here instead of outside the else 
             # block because we do not want to pause if we have servers              # block because we do not want to pause if we have servers
             # left to contact.                # left to contact.  
               if (scalar (keys(%Server_status))) {
                   &update_status($r,
                          &mt('waiting on').' '.(join(' ',keys(%Server_status))));
               }
             sleep(1)              sleep(1)
         }          }
         #          #
         if (scalar (keys(%Server_status))) {  
             &update_status($r,'waiting on '.(join(' ',keys(%Server_status))));  
         }  
         #          #
         # Loop through the servers we have contacted but do not          # Loop through the servers we have contacted but do not
         # have results from yet, looking for results.          # have results from yet, looking for results.
Line 2029  END Line 2184  END
             $status=~/^([\.\w]+)$/;               $status=~/^([\.\w]+)$/; 
            my $datafile=$r->dir_config('lonDaemons').'/tmp/'.$1;             my $datafile=$r->dir_config('lonDaemons').'/tmp/'.$1;
             if (-e $datafile && ! -e "$datafile.end") {              if (-e $datafile && ! -e "$datafile.end") {
                 &update_status($r,'Receiving results from '.$server);                  &update_status($r,&mt('Receiving results from').' '.$server);
                 next;                  next;
             }              }
             last if ($connection->aborted());              last if ($connection->aborted());
             if (-e "$datafile.end") {              if (-e "$datafile.end") {
                 &update_status($r,'Reading results from '.$server);                  &update_status($r,&mt('Reading results from').' '.$server);
                 if (-z "$datafile") {                  if (-z "$datafile") {
                     delete($Server_status{$server});                      delete($Server_status{$server});
                     next;                      next;
Line 2089  END Line 2244  END
             &update_seconds($r,$time_remaining);              &update_seconds($r,$time_remaining);
         }          }
     }      }
     &update_status($r,'Search Complete'.$server);      &update_status($r,&mt('Search Complete').$server);
     &update_seconds($r,0);      &update_seconds($r,0);
     &Apache::lonmysql::disconnect_from_db();      &Apache::lonmysql::disconnect_from_db();
     # We have run out of time or run out of servers to talk to and      # We have run out of time or run out of servers to talk to and
Line 2161  sub prev_next_buttons { Line 2316  sub prev_next_buttons {
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
 sub display_results {  sub display_results {
     my ($r,$importbutton,$closebutton) = @_;      my ($r,$importbutton,$closebutton,$diropendb) = @_;
     my $connection = $r->connection;      my $connection = $r->connection;
     $r->print(&search_results_header($importbutton,$closebutton));      $r->print(&search_results_header($importbutton,$closebutton));
     ##      ##
Line 2233  sub display_results { Line 2388  sub display_results {
          ."</center>\n"           ."</center>\n"
          );           );
     if ($total_results == 0) {      if ($total_results == 0) {
         $r->print("There are currently no results.\n".          $r->print('<meta HTTP-EQUIV="Refresh" CONTENT="1">'.
                     '<h3>'.&mt('There are currently no results').'.</h3>'.
                   "</form></body></html>");                    "</form></body></html>");
         return;          return;
     } else {      } else {
Line 2250  sub display_results { Line 2406  sub display_results {
     ##      ##
     foreach my $row (@Results) {      foreach my $row (@Results) {
         if ($connection->aborted()) {          if ($connection->aborted()) {
             untie %groupsearch_db if (tied(%groupsearch_db));              &cleanup();
             &Apache::lonmysql::disconnect_from_db();  
             return;              return;
         }          }
         my %Fields = %{&parse_row(@$row)};          my %Fields = %{&parse_row(@$row)};
Line 2265  sub display_results { Line 2420  sub display_results {
         $r->rflush();          $r->rflush();
     }      }
     if (@Results < 1) {      if (@Results < 1) {
         $r->print("There were no results matching your query");          $r->print(&mt("There were no results matching your query"));
     } else {      } else {
         $r->print          $r->print
             ('<center>'.              ('<center>'.
Line 2338  sub parse_row { Line 2493  sub parse_row {
     my @Row = @_;      my @Row = @_;
     my %Fields;      my %Fields;
     for (my $i=0;$i<=$#Row;$i++) {      for (my $i=0;$i<=$#Row;$i++) {
         $Fields{$DataOrder[$i]}=&Apache::lonnet::unescape($Row[$i]);          $Fields{$Datatypes[$i]->{'name'}}=&Apache::lonnet::unescape($Row[$i]);
     }      }
     $Fields{'language'} =       $Fields{'language'} = 
         &Apache::loncommon::languagedescription($Fields{'lang'});          &Apache::loncommon::languagedescription($Fields{'language'});
     $Fields{'copyrighttag'} =      $Fields{'copyrighttag'} =
         &Apache::loncommon::copyrightdescription($Fields{'copyright'});          &Apache::loncommon::copyrightdescription($Fields{'copyright'});
     $Fields{'mimetag'} =      $Fields{'mimetag'} =
Line 2357  sub parse_row { Line 2512  sub parse_row {
 =item &parse_raw_result()  =item &parse_raw_result()
   
 Takes a line from the file of results and parse it.  Returns a hash   Takes a line from the file of results and parse it.  Returns a hash 
 with keys for the following fields:  with keys according to column labels
 'title', 'author', 'subject', 'url', 'keywords', 'version', 'notes',   
 'abstract', 'mime', 'lang', 'owner', 'copyright', 'creationdate',   
 'lastrevisiondate'.  
   
 In addition, the following tags are set by calling the appropriate   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.  The 'title' field is set to "Untitled" if the title field is blank.
   
Line 2378  sub parse_raw_result { Line 2530  sub parse_raw_result {
     # Check for a comma - if it is there then we do not need to unescape the      # 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      # string.  There seems to be some kind of problem with some items in
     # the database - the entire string gets sent out unescaped...?      # the database - the entire string gets sent out unescaped...?
     unless ($result =~ /,/) {  #    unless ($result =~ /,/) {
         $result = &Apache::lonnet::unescape($result);  #        $result = &Apache::lonnet::unescape($result);
     }  #    }
     my @fields=map {  # conclude from self to others regarding fields
         &Apache::lonnet::unescape($_);      my %Fields=&Apache::lonmeta::metadata_col_to_hash(
     } (split(/\,/,$result));   map {
     my ($title,$author,$subject,$url,$keywords,$version,   &Apache::lonnet::unescape($_);
         $notes,$abstract,$mime,$lang,   } (split(/\,/,$result))
         $creationdate,$lastrevisiondate,$owner,$copyright)=@fields;        );
     my %Fields =   # prettier display
         ( 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'} =       $Fields{'language'} = 
         &Apache::loncommon::languagedescription($Fields{'lang'});          &Apache::loncommon::languagedescription($Fields{'language'});
     $Fields{'copyrighttag'} =      $Fields{'copyrighttag'} =
         &Apache::loncommon::copyrightdescription($Fields{'copyright'});          &Apache::loncommon::copyrightdescription($Fields{'copyright'});
     $Fields{'mimetag'} =      $Fields{'mimetag'} =
Line 2418  sub parse_raw_result { Line 2555  sub parse_raw_result {
         $Fields{'title'}='Untitled';           $Fields{'title'}='Untitled'; 
     }      }
     unless ($ENV{'user.adv'}) {      unless ($ENV{'user.adv'}) {
         # What is this anyway?          # do not show descriptive information to non-advanced users
         $Fields{'keywords'} = '- not displayed -';          $Fields{'keywords'} = '- not displayed -';
         $Fields{'notes'}    = '- not displayed -';          $Fields{'notes'}    = '- not displayed -';
         $Fields{'abstract'} = '- not displayed -';          $Fields{'abstract'} = '- not displayed -';
Line 2508  Checked for existance & 'edit' mode. Line 2645  Checked for existance & 'edit' mode.
   
 =item 'form.form'  =item 'form.form'
   
   Contains the name of the form that has the input fields to set
   
 =item 'form.element'  =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  =back
   
 =cut  =cut
Line 2518  Checked for existance & 'edit' mode. Line 2663  Checked for existance & 'edit' mode.
 ######################################################################  ######################################################################
 sub search_results_header {  sub search_results_header {
     my ($importbutton,$closebutton) = @_;      my ($importbutton,$closebutton) = @_;
       my $bodytag=&Apache::loncommon::bodytag(undef,undef,undef,1);
     my $result = '';      my $result = '';
     # output beginning of search page      # output beginning of search page
     # conditional output of script functions dependent on the mode in      # conditional output of script functions dependent on the mode in
Line 2546  SCRIPT Line 2692  SCRIPT
         } elsif ($ENV{'form.mode'} eq 'edit') {          } elsif ($ENV{'form.mode'} eq 'edit') {
             my $form = $ENV{'form.form'};              my $form = $ENV{'form.form'};
             my $element = $ENV{'form.element'};              my $element = $ENV{'form.element'};
               my $titleelement = $ENV{'form.titleelement'};
       my $changetitle;
       if (!$titleelement) {
    $changetitle='function changeTitle(val) {}';
       } else {
       $changetitle=<<END;
   function changeTitle(val) {
       if (parent.targetwin.document) {
           parent.targetwin.document.forms["$form"].elements["$titleelement"].value=val;
       } else {
    var url = 'forms[\"$form\"].elements[\"$titleelement\"].value';
           alert("Unable to transfer data to "+url);
       }
   }
   END
               }
   
             $result.=<<SCRIPT;              $result.=<<SCRIPT;
 <script type="text/javascript">  <script type="text/javascript">
 function select_data(title,url) {  function select_data(title,url) {
     changeURL(url);      changeURL(url);
       changeTitle(title);
     parent.close();      parent.close();
 }  }
 function changeTitle(val) {  $changetitle
 }  
 function changeURL(val) {  function changeURL(val) {
     if (parent.targetwin.document) {      if (parent.targetwin.document) {
         parent.targetwin.document.forms["$form"].elements["$element"].value=val;          parent.targetwin.document.forms["$form"].elements["$element"].value=val;
Line 2569  SCRIPT Line 2732  SCRIPT
     $result.=<<SCRIPT if $ENV{'form.catalogmode'} eq 'groupsearch';      $result.=<<SCRIPT if $ENV{'form.catalogmode'} eq 'groupsearch';
 <script type="text/javascript">  <script type="text/javascript">
     function queue(checkbox_num,val) {      function queue(checkbox_num,val) {
         if (document.forms.results.returnvalues[checkbox_num].checked) {          if (document.forms.results.returnvalues.length != "undefined" &&
             parent.statusframe.document.forms.statusform.elements.Queue.value +='1a'+val+'b';              typeof(document.forms.results.returnvalues.length) == "number") {
               if (document.forms.results.returnvalues[checkbox_num].checked) {
                   parent.statusframe.document.forms.statusform.elements.Queue.value +='1a'+val+'b';
               } else {
                   parent.statusframe.document.forms.statusform.elements.Queue.value +='0a'+val+'b';
               }
         } else {          } else {
             parent.statusframe.document.forms.statusform.elements.Queue.value +='0a'+val+'b';              if (document.forms.results.returnvalues.checked) {
                   parent.statusframe.document.forms.statusform.elements.Queue.value +='1a'+val+'b';
               } else {
                   parent.statusframe.document.forms.statusform.elements.Queue.value +='0a'+val+'b';
               }
         }          }
     }      }
     function select_group() {      function select_group() {
Line 2595  END Line 2767  END
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
 sub search_status_header {  sub search_status_header {
       my $bodytag=&Apache::loncommon::bodytag(undef,undef,undef,1);
     return <<ENDSTATUS;      return <<ENDSTATUS;
 <html><head><title>Search Status</title></head>  <html><head><title>Search Status</title></head>
 $bodytag  $bodytag
Line 2662  extra custom metadata to show. Line 2835  extra custom metadata to show.
 ######################################################################  ######################################################################
 sub detailed_citation_view {  sub detailed_citation_view {
     my ($prefix,%values) = @_;      my ($prefix,%values) = @_;
       my $icon=&Apache::loncommon::icon($values{'url'});
     my $result=<<END;      my $result=<<END;
 <b>$prefix<a href="http://$ENV{'HTTP_HOST'}$values{'url'}"   <b>$prefix<img src="$icon" /><a href="http://$ENV{'HTTP_HOST'}$values{'url'}" 
     target='search_preview'>$values{'title'}</a></b>      target='search_preview'>$values{'title'}</a></b>
 <p>  <p>
 <b>$values{'author'}</b>, <i>$values{'owner'}</i><br />  <b>$values{'author'}</b>, <i>$values{'owner'}</i><br />
Line 2673  sub detailed_citation_view { Line 2847  sub detailed_citation_view {
 <b>Notes:         </b> $values{'notes'}<br />  <b>Notes:         </b> $values{'notes'}<br />
 <b>MIME Type:     </b> $values{'mimetag'}<br />  <b>MIME Type:     </b> $values{'mimetag'}<br />
 <b>Language:      </b> $values{'language'}<br />  <b>Language:      </b> $values{'language'}<br />
 <b>Copyright/Distribution:</b> $values{'cprtag'}<br />  <b>Copyright/Distribution:</b> $values{'copyrighttag'}<br />
 </p>  </p>
 $values{'extrashow'}  $values{'extrashow'}
 <p>  <p>
Line 2696  END Line 2870  END
 ######################################################################  ######################################################################
 sub summary_view {  sub summary_view {
     my ($prefix,%values) = @_;      my ($prefix,%values) = @_;
       my $icon=&Apache::loncommon::icon($values{'url'});
     my $result=<<END;      my $result=<<END;
 $prefix<a href="http://$ENV{'HTTP_HOST'}$values{'url'}"   $prefix<img src="$icon" /><a href="http://$ENV{'HTTP_HOST'}$values{'url'}" 
    target='search_preview'>$values{'author'}</a><br />     target='search_preview'>$values{'author'}</a><br />
 $values{'title'}<br />  $values{'title'}<br />
 $values{'owner'} -- $values{'lastrevisiondate'}<br />  $values{'owner'} -- $values{'lastrevisiondate'}<br />
Line 2722  END Line 2897  END
 ######################################################################  ######################################################################
 sub compact_view {  sub compact_view {
     my ($prefix,%values) = @_;      my ($prefix,%values) = @_;
       my $icon=&Apache::loncommon::icon($values{'url'});
     my $result=<<END;      my $result=<<END;
 $prefix <a href="http://$ENV{'HTTP_HOST'}$values{'url'}"  target='search_preview'>  $prefix <img src="$icon" /> <a href="http://$ENV{'HTTP_HOST'}$values{'url'}"  target='search_preview'>
 $values{'title'}</a>  $values{'title'}</a>
 <b>$values{'author'}</b><br />  <b>$values{'author'}</b><br />
 END  END
Line 2744  END Line 2920  END
 ######################################################################  ######################################################################
 sub fielded_format_view {  sub fielded_format_view {
     my ($prefix,%values) = @_;      my ($prefix,%values) = @_;
       my $icon=&Apache::loncommon::icon($values{'url'});
     my $result=<<END;      my $result=<<END;
 $prefix  $prefix <img src="$icon" />
 <b>URL: </b> <a href="http://$ENV{'HTTP_HOST'}$values{'url'}"   <b>URL: </b> <a href="http://$ENV{'HTTP_HOST'}$values{'url'}" 
               target='search_preview'>$values{'url'}</a>                target='search_preview'>$values{'url'}</a>
 <br />  <br />
Line 2799  $prefix Line 2976  $prefix
 &lt;mimetag&gt;$values{'mimetag'}&lt;/mimetag&gt;  &lt;mimetag&gt;$values{'mimetag'}&lt;/mimetag&gt;
 &lt;/mimeInfo&gt;  &lt;/mimeInfo&gt;
 &lt;languageInfo&gt;  &lt;languageInfo&gt;
 &lt;language&gt;$values{'lang'}&lt;/language&gt;  &lt;language&gt;$values{'language'}&lt;/language&gt;
 &lt;languagetag&gt;$values{'language'}&lt;/languagetag&gt;  &lt;languagetag&gt;$values{'languagetag'}&lt;/languagetag&gt;
 &lt;/languageInfo&gt;  &lt;/languageInfo&gt;
 &lt;creationdate&gt;$values{'creationdate'}&lt;/creationdate&gt;  &lt;creationdate&gt;$values{'creationdate'}&lt;/creationdate&gt;
 &lt;lastrevisiondate&gt;$values{'lastrevisiondate'}&lt;/lastrevisiondate&gt;  &lt;lastrevisiondate&gt;$values{'lastrevisiondate'}&lt;/lastrevisiondate&gt;
Line 2861  $parms is extra information to include i Line 3038  $parms is extra information to include i
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
 sub output_blank_field_error {  sub output_blank_field_error {
     my ($r,$closebutton,$parms)=@_;      my ($r,$closebutton,$parms,$hidden_fields)=@_;
       my $bodytag=&Apache::loncommon::bodytag(undef,undef,undef,1);
     # make query information persistent to allow for subsequent revision      # make query information persistent to allow for subsequent revision
     $r->print(<<BEGINNING);      $r->print(<<BEGINNING);
 <html>  <html>
Line 2910  Inputs: Line 3088  Inputs:
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
 sub output_date_error {  sub output_date_error {
     my ($r,$message,$closebutton)=@_;      my ($r,$message,$closebutton,$hidden_fields)=@_;
     # make query information persistent to allow for subsequent revision      # make query information persistent to allow for subsequent revision
       my $bodytag=&Apache::loncommon::bodytag(undef,undef,undef,1);
     $r->print(<<RESULTS);      $r->print(<<RESULTS);
 <html>  <html>
 <head>  <head>
Line 2963  sub start_fresh_session { Line 3142  sub start_fresh_session {
   
 1;  1;
   
   sub cleanup {
       if (tied(%groupsearch_db)) {
           unless (untie(%groupsearch_db)) {
     &Apache::lonnet::logthis('Failed cleanup searchcat: groupsearch_db');
           }
       }
       &untiehash();
       &Apache::lonmysql::disconnect_from_db();
   }
   
 __END__  __END__
   
 =pod  =pod

Removed from v.1.161  
changed lines
  Added in v.1.199


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>