Diff for /loncom/interface/lonsearchcat.pm between versions 1.144 and 1.145

version 1.144, 2002/07/26 16:37:58 version 1.145, 2002/07/28 20:02:14
Line 103  use Apache::lonmysql(); Line 103  use Apache::lonmysql();
   
 =over 4  =over 4
   
 =item $closebutton  
   
 button that closes the search window  
   
 =item $importbutton  =item $importbutton
   
 button to take the select results and go to group sorting  button to take the select results and go to group sorting
Line 127  that produces it.  Adding a new view typ Line 123  that produces it.  Adding a new view typ
 adding a line to the definition of this hash and making sure the function  adding a line to the definition of this hash and making sure the function
 takes the proper parameters.  takes the proper parameters.
   
 =item $results_db  
   
 The name of the database results from searches are put in.  
   
 =back   =back 
   
 =cut  =cut
Line 139  The name of the database results from se Line 131  The name of the database results from se
 ######################################################################  ######################################################################
   
 # -- dynamically rendered interface components  # -- 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  my $importbutton; # button to take the selected results and go to group sorting
   
 # -- miscellaneous variables  # -- miscellaneous variables
 my %groupsearch_db;     # database hash  my %groupsearch_db;     # database hash
 my $diropendb = "";    # db file  my $diropendb = "";    # db file
   
 my $results_db = "";  
 #             View Description           Function Pointer  #             View Description           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 );
   my $persistent_db_file;
   my %persistent_db;
   my $hidden_fields;
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
   
Line 180  string that holds portions of the screen Line 171  string that holds portions of the screen
 ######################################################################  ######################################################################
 sub handler {  sub handler {
     my $r = shift;      my $r = shift;
     untie %groupsearch_db;      #
       untie %groupsearch_db if (tied(%groupsearch_db));
       #
       my $closebutton;  # button that closes the search window 
                         # This button is different for the RAT compared to
                         # normal invocation.
       #
     $r->content_type('text/html');      $r->content_type('text/html');
     $r->send_http_header;      $r->send_http_header;
     return OK if $r->header_only;      return OK if $r->header_only;
       ## 
       ## Pick up form fields passed in the links.
       ##
       &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                ['catalogmode','launch','acts','mode','form','element',
                 'reqinterface','persistent_db_id','table']);
     ##      ##
     ## 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/".&Apache::lonnet::escape($domain).
             "\_".&Apache::lonnet::escape($ENV{'user.name'})."_searchcat.db";              "\_".&Apache::lonnet::escape($ENV{'user.name'})."_searchcat.db";
     $results_db = "/home/httpd/perl/tmp/".&Apache::lonnet::escape($domain).      #
         '_'.&Apache::lonnet::escape($ENV{'user.name'})."_searchresults.db";      # set the name of the persistent database
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},      # $ENV{'form.persistent_db_id'} can only have digits in it.
              ['catalogmode','launch','acts','mode','form','element',      if (! exists($ENV{'form.persistent_db_id'}) ||
               'reqinterface']);              $ENV{'form.persistent_db_id'} =~ /\D/ ) {
           $ENV{'form.persistent_db_id'} = time;
       }
       $persistent_db_file = "/home/httpd/perl/tmp/".
           &Apache::lonnet::escape($domain).
               '_'.&Apache::lonnet::escape($ENV{'user.name'}).
                   '_'.$ENV{'form.persistent_db_id'}.'_persistent_search.db';
       #
       # Read in the database.  It should (hopefully) not be catastrophic to
       #    fail in this exercise. 
       if (-e $persistent_db_file) {
           # Read in the previous values, if we can.
    if (tie(%persistent_db,'GDBM_File',$persistent_db_file,
                   &GDBM_READER,0640)) {
               &reconstruct_persistent_form_data($r);
               untie (%persistent_db);
    }
       }
     ##      ##
     ## Clear out old values from groupsearch database      ## Clear out old values from groupsearch database
     ##      ##
Line 210  sub handler { Line 229  sub handler {
  }   }
     }      }
     ##      ##
     ## Produce some output, so people know it is working  
     ##  
     $r->print("\n");  
     $r->rflush;  
     ##  
     ## Configure dynamic components of interface      ## Configure dynamic components of interface
     ##      ##
     my $hidden;       # Holds 'hidden' html forms      $hidden_fields = '<input type="hidden" name="persistent_db_id" value="'.
           $ENV{'form.persistent_db_id'}.'" />';
     if ($ENV{'form.catalogmode'} eq 'interactive') {      if ($ENV{'form.catalogmode'} eq 'interactive') {
  $hidden="<input type='hidden' name='catalogmode' value='interactive'>".  
     "\n";  
         $closebutton="<input type='button' name='close' value='CLOSE' ".          $closebutton="<input type='button' name='close' value='CLOSE' ".
     "onClick='self.close()'>"."\n";      "onClick='self.close()'>"."\n";
     } elsif ($ENV{'form.catalogmode'} eq 'groupsearch') {      } elsif ($ENV{'form.catalogmode'} eq 'groupsearch') {
  $hidden=<<END;  
 <input type='hidden' name='catalogmode' value='groupsearch'>  
 END  
         $closebutton=<<END;          $closebutton=<<END;
 <input type='button' name='close' value='CLOSE' onClick='self.close()'>  <input type='button' name='close' value='CLOSE' onClick='self.close()'>
 END  END
Line 235  END Line 245  END
 onClick='javascript:select_group()'>  onClick='javascript:select_group()'>
 END  END
     }      }
     $hidden .= &make_persistent({ "form.mode"    => $ENV{'form.mode'},  
                                   "form.form"    => $ENV{'form.form'},  
                                   "form.element" => $ENV{'form.element'},  
                                   "form.date"    => 2 });  
     ##      ##
     ##  What are we doing?      ##  Do a search, if needed.
     ##      ##
     my $searchtype;      my $searchtype;
     $searchtype = 'Basic'    if ($ENV{'form.basicsubmit'}    eq 'SEARCH');      $searchtype = 'Basic'    if ($ENV{'form.basicsubmit'}    eq 'SEARCH');
     $searchtype = 'Advanced' if ($ENV{'form.advancedsubmit'} eq 'SEARCH');      $searchtype = 'Advanced' if ($ENV{'form.advancedsubmit'} eq 'SEARCH');
     if ($searchtype) {      if ($searchtype) {
           ##
           ## make query information persistent to allow for subsequent revision
           ##
           tie(%persistent_db,'GDBM_File',$persistent_db_file,&GDBM_WRCREAT,0640);
           &make_persistent(\%ENV);
           untie(%persistent_db);
           #
         # We are running a search          # We are running a search
         my ($query,$customquery,$customshow,$libraries) =           my ($query,$customquery,$customshow,$libraries) = 
             (undef,undef,undef,undef);              (undef,undef,undef,undef);
         my $pretty_string;          my $pretty_string;
         if ($searchtype eq 'Basic') {          if ($searchtype eq 'Basic') {
             ($query,$pretty_string) = &parse_basic_search($r);              ($query,$pretty_string) = &parse_basic_search($r,$closebutton);
         } elsif ($ENV{'form.advancedsubmit'} eq 'SEARCH') {          } elsif ($ENV{'form.advancedsubmit'} eq 'SEARCH') {
             ($query,$customquery,$customshow,$libraries,$pretty_string)               ($query,$customquery,$customshow,$libraries,$pretty_string) 
                 = &parse_advanced_search($r);                  = &parse_advanced_search($r,$closebutton);
             return OK if (! defined($query));              return OK if (! defined($query));
         }          }
         # Output some information to the user.          # Output some information to the user.
Line 262  END Line 275  END
         $r->print("Sending search request to LON-CAPA servers.<br />\n");          $r->print("Sending search request to LON-CAPA servers.<br />\n");
         $r->rflush();          $r->rflush();
         &run_search($r,$query,$customquery,$customshow,$libraries);          &run_search($r,$query,$customquery,$customshow,$libraries);
         &display_results($r,$searchtype,$hidden,$importbutton,          ##
                          $closebutton);          ## Display the results
           ##
           &display_results($r,$searchtype,$importbutton,$closebutton);
         $r->rflush();          $r->rflush();
     } else {      } else {
         #          #
         # We need to get information to search on  
         #  
         # Set the default view if it is not already set.          # Set the default view if it is not already set.
         if (!defined($ENV{'form.viewselect'})) {          if (!defined($ENV{'form.viewselect'})) {
             $ENV{'form.viewselect'} ="Detailed Citation View";              $ENV{'form.viewselect'} ="Detailed Citation View";
         }          }
         # Output the advanced interface          # 
         if ($ENV{'form.reqinterface'} eq 'advanced') {          # remove the requested interface from the environment.
             $r->print(&advanced_search_form($closebutton,$hidden));          my $interface;
         } else {           if ($ENV{'form.reqinterface'}) {
               $interface = lc($ENV{'form.reqinterface'});
           } else {
               $interface = 'basic';
           }
           ##
           ## Determine course of action
           ##
           if ($interface eq 'display') {
               # &display_results($closebutton));
           } elsif ($interface eq 'advanced') {
               $r->print(&advanced_search_form($closebutton));
           } elsif ($interface eq 'basic') { 
             # Output normal search interface              # Output normal search interface
             $r->print(&basic_search_form($closebutton,$hidden));              $r->print(&basic_search_form($closebutton));
         }          }
     }      }
       untie (%persistent_db);
     return OK;      return OK;
 }   } 
   
Line 300  Returns a scalar which holds html for th Line 325  Returns a scalar which holds html for th
 ######################################################################  ######################################################################
   
 sub basic_search_form{  sub basic_search_form{
     my ($closebutton,$hidden) = @_;      my ($closebutton) = @_;
     my $scrout=<<"ENDDOCUMENT";      my $scrout=<<"ENDDOCUMENT";
 <html>  <html>
 <head>  <head>
Line 317  sub basic_search_form{ Line 342  sub basic_search_form{
 <img align='right' src='/adm/lonIcons/lonlogos.gif' />  <img align='right' src='/adm/lonIcons/lonlogos.gif' />
 <h1>Search Catalog</h1>  <h1>Search Catalog</h1>
 <form method="post" action="/adm/searchcat">  <form method="post" action="/adm/searchcat">
 $hidden  $hidden_fields
 <h3>Basic Search</h3>  <h3>Basic Search</h3>
 <p>  <p>
 Enter terms or phrases separated by AND, OR, or NOT   Enter terms or phrases separated by AND, OR, or NOT 
Line 369  Returns a scalar which holds html for th Line 394  Returns a scalar which holds html for th
 ######################################################################  ######################################################################
   
 sub advanced_search_form{  sub advanced_search_form{
     my ($closebutton,$hidden) = @_;      my ($closebutton) = @_;
     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 401  Enter terms or phrases separated by sear Line 426  Enter terms or phrases separated by sear
 such as AND, OR, or NOT.<br />  such as AND, OR, or NOT.<br />
 <form method="post" action="/adm/searchcat">  <form method="post" action="/adm/searchcat">
 $advanced_buttons  $advanced_buttons
 $hidden  $hidden_fields
 <table>  <table>
 <tr><td><font color="#800000" face="helvetica"><b>VIEW:</b></font></td>  <tr><td><font color="#800000" face="helvetica"><b>VIEW:</b></font></td>
 <td>  <td>
Line 453  ENDHEADER Line 478  ENDHEADER
     # 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);      my $size = (scalar @domains < ($size - 1) ? scalar @domains + 1 : $size);
     # standalone machines do not get to choose a domain to search.      $scrout.="\n".'<font color="#800000" face="helvetica"><b>'.
     if ((scalar @domains) == 1) {          'DOMAINS</b></font><br />'.
         $scrout .='<input type="hidden" name="domains" value="any" />'."\n";              '<select name="domains" size="'.$size.'" multiple>'."\n".
     } else {                  '<option name="any" value="any" '.
         $scrout.="\n".'<font color="#800000" face="helvetica"><b>'.                      ($domain_hash{'any'}? 'selected ' :'').
             'DOMAINS</b></font><br />'.  
                 '<select name="domains" size="'.$size.'" multiple>'."\n".  
                     '<option name="any" value="any" '.  
                         ($domain_hash{'any'}? 'selected ' :'').  
                         '>all domains</option>'."\n";                          '>all domains</option>'."\n";
         foreach my $dom (sort @domains) {      foreach my $dom (sort @domains) {
             $scrout.="<option name=\"$dom\" ".          $scrout.="<option name=\"$dom\" ".
                 ($domain_hash{$dom} ? 'selected ' :'').">$dom</option>\n";              ($domain_hash{$dom} ? 'selected ' :'').">$dom</option>\n";
         }  
         $scrout.="</select>\n";  
     }      }
       $scrout.="</select>\n";
     #----------------------------------------------------------------      #----------------------------------------------------------------
     $scrout.=&selectbox('Limit by language','language',      $scrout.=&selectbox('Limit by language','language',
  $ENV{'form.language'},'any','Any Language',   $ENV{'form.language'},'any','Any Language',
Line 556  ENDDOCUMENT Line 576  ENDDOCUMENT
   
 =pod   =pod 
   
 =item &make_persistent()   =item &reconstruct_persistent_form_data
   
 Returns a scalar which holds the current ENV{'form.*'} values in  This function is the reverse of &make_persistent();
 a 'hidden' html input tag.  This allows search interface information  Retrieve persistent data from %persistent_db.  Retrieved items will have their
 to be somewhat persistent.  values unescaped.  If the item contains commas (before unescaping), the
   returned value will be an array pointer.  Items will be returned in the
   environment in $ENV{"form.$name"}.
   
 =cut  =cut
   
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
   sub reconstruct_persistent_form_data {
       foreach my $name (keys %persistent_db) {
           # &Apache::lonnet::logthis("Reconstructing $name = $persistent_db{$name}");
           my @Values = split(',',$persistent_db{$name});
           my @value = map { &Apache::lonnet::unescape($_) } @Values;
           $name = 'form.'.$name;
           if (exists($ENV{$name})) {
               if (ref($ENV{$name})) {
                   # Assume it is an array reference
                   $ENV{$name} = [@{$ENV{$name}},@value];
               } else {
                   $ENV{$name} = [$ENV{$name},@value];
               }
           } else {
               if (@value > 1) {
                   $ENV{$name} = [@value];
               } else {
                   $ENV{$name} = $value[0];
               }
           }
       }
       return;
   }
   
   ######################################################################
   ######################################################################
   
   =pod 
   
   =item &make_persistent() 
   
   Store (environment) variables away to the %persistent_db.  
   Values will be escaped.  Values that are array pointers will have their
   elements escaped and concatenated in a comma seperated string.  
   
   =cut
   
   ######################################################################
   ######################################################################
 sub make_persistent {  sub make_persistent {
     my %save = %{shift()};      my %save = %{shift()};
     my $persistent='';  
     foreach my $name (keys %save) {      foreach my $name (keys %save) {
  if ($name =~ /^form\./ && $name !~ /submit/) {          next if ($name !~ /^form\./ || $name =~ /submit/);
             my @values = (ref($save{$name}) ? @{$save{$name}} : ($save{$name}));          my @values = (ref($save{$name}) ? @{$save{$name}} : ($save{$name}));
     $name=~s/^form\.//;          # We handle array references, but not recursively.
             foreach (@values) {          my $store = join(',', map { &Apache::lonnet::escape($_); } @values );
                 s/\"/\'/g; # do not mess with html field syntax          $name=~s/^form\.//;
                 next if (! $_ );          $persistent_db{$name} = $store;
                 $persistent.=<<END;  
 <input type="hidden" name="$name" value="$_" />  
 END  
             }  
         }  
     }      }
     return $persistent;      return '';
 }  }
   
 ######################################################################  ######################################################################
Line 893  Parse advanced search form and return th Line 947  Parse advanced search form and return th
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
 sub parse_advanced_search {  sub parse_advanced_search {
     my ($r)=@_;      my ($r,$closebutton)=@_;
     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 929  sub parse_advanced_search { Line 983  sub parse_advanced_search {
  }   }
     }      }
     unless ($fillflag) {      unless ($fillflag) {
  &output_blank_field_error($r);   &output_blank_field_error($r,$closebutton);
  return ;   return ;
     }      }
     # Turn the form input into a SQL-based query      # Turn the form input into a SQL-based query
Line 992  sub parse_advanced_search { Line 1046  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);   &output_date_error($r,$datequery,$closebutton);
  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 1072  Parse the basic search form and return a Line 1126  Parse the basic search form and return a
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
 sub parse_basic_search {  sub parse_basic_search {
     my ($r)=@_;      my ($r,$closebutton)=@_;
     # Clean up fields for safety      # Clean up fields for safety
     for my $field ('basicexp') {      for my $field ('basicexp') {
  $ENV{"form.$field"}=~s/[^\w\s\(\)\-]//g;   $ENV{"form.$field"}=~s/[^\w\s\(\)\-]//g;
Line 1086  sub parse_basic_search { Line 1140  sub parse_basic_search {
   
     # 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);   &output_blank_field_error($r,$closebutton);
  return OK;   return OK;
     }      }
     my $pretty_search_string = '<b>'.$ENV{'form.basicexp'}.'</b>';      my $pretty_search_string = '<b>'.$ENV{'form.basicexp'}.'</b>';
Line 1432  sub write_status { Line 1486  sub write_status {
 sub run_search {  sub run_search {
     my ($r,$query,$customquery,$customshow,$serverlist) = @_;      my ($r,$query,$customquery,$customshow,$serverlist) = @_;
     #      #
       # Timing variables
       #
       my $starttime = time;
       my $max_time  = 120;  # seconds for the search to complete
       #
       # Determine the servers we need to contact.
       #
     my @Servers_to_contact;      my @Servers_to_contact;
     if (defined($serverlist)) {      if (defined($serverlist)) {
         @Servers_to_contact = @$serverlist;          @Servers_to_contact = @$serverlist;
Line 1440  sub run_search { Line 1501  sub run_search {
     }      }
     my %Server_status;      my %Server_status;
     #      #
     # Timing variables  
     my $starttime = time;  
     my $max_time  = 120;  # seconds for the search to complete  
     #  
     # Create Table      # Create Table
     #####################################      #
     my $table = &Apache::lonmysql::create_table      my $table = &Apache::lonmysql::create_table
         ( { columns => \%Datatypes,          ( { columns => \%Datatypes,
             column_order => \@DataOrder,              column_order => \@DataOrder,
Line 1460  sub run_search { Line 1517  sub run_search {
                   " your system administrator.");                    " your system administrator.");
         return;          return;
     }      }
       ##
       ## form.table needs to be stored in the persistent database...
       ## 
     $ENV{'form.table'}=$table;      $ENV{'form.table'}=$table;
     #      #
     #####################################      # Prepare for the big loop.
       #
     my $hitcountsum;      my $hitcountsum;
     my $server;       my $server; 
     my $status;      my $status;
Line 1474  sub run_search { Line 1535  sub run_search {
             my $server = shift(@Servers_to_contact);              my $server = shift(@Servers_to_contact);
             my $reply=&Apache::lonnet::metadata_query($query,$customquery,              my $reply=&Apache::lonnet::metadata_query($query,$customquery,
                                                       $customshow,[$server]);                                                        $customshow,[$server]);
             # We should let the user know we have contacted another server  
             ($server) = keys(%$reply);              ($server) = keys(%$reply);
             $Server_status{$server} = $reply->{$server};              $Server_status{$server} = $reply->{$server};
             # &write_status($r,"Contacted:$server:reply:".              # &write_status($r,"Contacted:$server:reply:".
             #                   $Server_status{$server});              #                   $Server_status{$server});
             # Hmmm, should we add to $max_time if we contact a server?              if ($max_time - (time - $starttime) < 20) {
                   # If there are less than 20 seconds to go in the search,
                   # give the newly contacted servers 20 more seconds to 
                   # respond....
                   $max_time += 20;
               }
         } else {          } else {
             sleep(1); # wait a sec. to give time for files to be written              sleep(1); # wait a sec. to give time for files to be written
         }          }
         while (my ($server,$status) = each(%Server_status)) {          while (my ($server,$status) = each(%Server_status)) {
             if ($status eq 'con_lost') {              if ($status eq 'con_lost') {
                 delete ($Server_status{$server});                  delete ($Server_status{$server});
                 # &write_status($r,"Removing $server");                  # &write_status($r,"server $server is not responding.");
                 next;                  next;
             }              }
             $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") {
                 # Let the user know we are receiving data from the server                  # Let the user know we are receiving data from the server
                 &write_status($r,"$server:Receiving file");                  # &write_status($r,"$server:Receiving file");
                 next;                  next;
             }              }
             if (-e "$datafile.end") {              if (-e "$datafile.end") {
Line 1506  sub run_search { Line 1571  sub run_search {
                     # Error opening file...                      # Error opening file...
                     # Tell the user and exit...?                      # Tell the user and exit...?
                     # Should I give up on opening it?                      # Should I give up on opening it?
                     &write_status("Unable to open $datafile");                      &write_status("Unable to open search results file for ".
                                     "server $server.  Omitting from search");
                     next;                      next;
                 }                  }
                 # Read in the whole file.                  # Read in the whole file.
Line 1530  sub run_search { Line 1596  sub run_search {
                 # $server is only deleted if the results file has been                   # $server is only deleted if the results file has been 
                 # found and (successfully) opened.  This may be a bad idea.                  # found and (successfully) opened.  This may be a bad idea.
                 delete($Server_status{$server});                  delete($Server_status{$server});
                   #&write_status($r,"Received $new_count more results from ".
                   #              $server.".");
             }              }
         }          }
         # Finished looping through the servers          # Finished looping through the servers
     }      }
     &Apache::lonmysql::disconnect_from_db();      &Apache::lonmysql::disconnect_from_db();
       # Let the user know
       #
     # 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
     # results to get.        # results to get.  
     if ($hitcountsum > 0) {      &write_status($r,"Search completed.");
         $r->print("<h3>Total results = $hitcountsum</h3></body></html>");      if ($hitcountsum) {
           &write_status($r,$hitcountsum." successful matches to your query.");
       } else {
           &write_status($r,"There were no successful matches to your query.");
     }      }
     return;      return;
 }  }
Line 1554  sub run_search { Line 1627  sub run_search {
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
 sub display_buttons {  sub display_buttons {
     my ($low,$high,$otherparms) = @_;      my ($current_min,$show,$total,$parms) = @_;
     my $maxshow = 20;      return '' if ($show eq 'all'); # No links if you get them all at once.
     my $lowest = ($low - $maxshow < 0 ? 0 : $low-$maxshow);      my $links;
     my $highest = $high + $maxshow;      ##
     my ($previous,$current,$next);      ## Prev
     if ($lowest < $low) {      my $prev_min = $current_min - $show;
         $previous = qq{<a href="/adm/searchcat?$otherparms&mode=display&low=$lowest&high=$highest">prev</a>};      $prev_min = 0 if $prev_min < 0;
     } else {      if ($prev_min < $current_min) {
         $previous = "prev";          $links .= qq{
   <a href="/adm/searchcat?$parms&startwith=$prev_min&show=$show">prev</a>
   };    
     }      }
     $current = qq{<a href="/adm/searchcat?$otherparms&mode=display&low=$low&high=$high">reload</a>};      ##
     $next = qq{<a href="/adm/searchcat?$otherparms&mode=display&low=$high&high=$highest">next</a>};      ## Pages.... Someday.
     my $result = $previous." ".$current." ".$next;      ##
     return $result;  
       ##
       ## Next
       my $next_min = $current_min + $show;
       my $next_min = $current_min if ($next_min > $total);
       if ($next_min != $current_min) {
           $links .= qq{
   <a href="/adm/searchcat?$parms&startwith=$next_min&show=$show">next</a>
   };    
       }
       return $links;
 }  }
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
Line 1581  sub display_buttons { Line 1666  sub display_buttons {
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
 sub display_results {  sub display_results {
     my ($r,$mode,$hidden,$importbutton,$closebutton) = @_;      my ($r,$mode,$importbutton,$closebutton) = @_;
     ##      ##
     ## Set viewing function      ## Set viewing function
     ##      ##
Line 1592  sub display_results { Line 1677  sub display_results {
         return;          return;
     }      }
     ##      ##
     ## make query information persistent to allow for subsequent revision  
     ##  
     my $persistent=&make_persistent(\%ENV);  
     ##  
     ## Get the catalog controls setup      ## Get the catalog controls setup
     ##      ##
     my $action = "/adm/searchcat";      my $action = "/adm/searchcat";
Line 1606  sub display_results { Line 1687  sub display_results {
     }      }
     $r->print(<<CATALOGCONTROLS);      $r->print(<<CATALOGCONTROLS);
 <form name='results' method="post" action="$action">  <form name='results' method="post" action="$action">
 $hidden  $hidden_fields
 <input type='hidden' name='acts' value='' />  <input type='hidden' name='acts' value='' />
 <input type='button' value='Revise search request'  <input type='button' value='Revise search request'
 onClick='this.form.submit();' />  onClick='this.form.submit();' />
 $importbutton  $importbutton
 $closebutton  $closebutton
 $persistent  
 <hr />  <hr />
 CATALOGCONTROLS  CATALOGCONTROLS
     if (! tie(%groupsearch_db,'GDBM_File',$diropendb,&GDBM_WRCREAT,0640)) {      if (! tie(%groupsearch_db,'GDBM_File',$diropendb,&GDBM_WRCREAT,0640)) {
Line 1620  CATALOGCONTROLS Line 1700  CATALOGCONTROLS
         $r->rflush();          $r->rflush();
         return;          return;
     }       } 
     #      ##
     my $fnum;      ## Prepare the table for querying
     # For now, just query the whole lot and spit them out.      ##
     my $table = $ENV{'form.table'};      my $table = $ENV{'form.table'};
     my $connection_result = &Apache::lonmysql::connect_to_db();      my $connection_result = &Apache::lonmysql::connect_to_db();
     if (!defined($connection_result)) {      if (!defined($connection_result)) {
         &write_status($r,&Apache::lonmysql::get_error());          &write_status($r,&Apache::lonmysql::get_error());
     }      }
     my @Results = &Apache::lonmysql::get_rows($table,'id>=0');      my $table_check = &Apache::lonmysql::check_table($table);
     #&write_status($r,&Apache::lonmysql::get_debug());      if (! defined($table_check)) {
     #&write_status($r,&Apache::lonmysql::get_error());          $r->print("A MySQL error has occurred.</body></html>");
           &Apache::lonnet::logthis("lonmysql was unable to determine the status".
                                    " of table ".$table);
           return;
       } elsif (! $table_check) {
           $r->print("The table of results could not be found.");
           &Apache::lonnet::logthis("The user requested a table, ".$table.
                                    ", that could not be found.");
           return;
       }
       ##
       ## Get the number of results 
       ##
       my $total_results = &Apache::lonmysql::number_of_rows($table);
       if (! defined($total_results)) {
           $r->print("A MySQL error has occurred.</body></html>");
           &Apache::lonnet::logthis("lonmysql was unable to determine the number".
                                    " of rows in table ".$table);
           &Apache::lonnet::logthis(&Apache::lonmysql::get_error());
           &Apache::lonnet::logthis(&Apache::lonmysql::get_debug());
           return;
       }
       if ($total_results == 0) {
           $r->print("There were no results matching your query.\n".
                     "</form></body></html>");
           return;
       }
       ##
       ## Determine how many results we need to get
       ##
       $ENV{'form.startwith'} = 0      if (! exists($ENV{'form.startwith'}));
       $ENV{'form.show'}      = 'all'  if (! exists($ENV{'form.show'}));
       my $min = $ENV{'form.startwith'};
       my $max;
       if ($ENV{'form.show'} eq 'all') {
           $max = $total_results ;
       } else {
           $max = $min + $ENV{'form.show'};
       }
       ##
       ## Output links (if necessary) for 'prev' and 'next' pages.
       ##
       
       ##
       ## Get results from MySQL table
       ##
       my @Results = &Apache::lonmysql::get_rows($table,
                                                 'id>'.$min.' AND id<='.$max);
       ##
       ## Loop through the results and output them.
       ##
     foreach my $row (@Results) {      foreach my $row (@Results) {
         my %Fields = %{&parse_row(@$row)};          my %Fields = %{&parse_row(@$row)};
         my $output="\n<p>\n";          my $output="<p>\n";
         if ($ENV{'form.catalogmode'} eq 'interactive') {          $output.=&catalogmode_output($Fields{'title'},$Fields{'url'});
             my $titleesc=$Fields{'title'};  
             $titleesc=~s/\'/\\'/; # '  
             if ($ENV{'form.catalogmode'} eq 'interactive') {  
                 $output.=<<END   
 <font size='-1'><INPUT TYPE="button" NAME="returnvalues" VALUE="SELECT"  
 onClick="javascript:select_data('$titleesc','$Fields{'url'}')">  
 </font>  
 <br />  
 END  
             }  
         }  
         if ($ENV{'form.catalogmode'} eq 'groupsearch') {  
             $fnum+=0;  
             $groupsearch_db{"pre_${fnum}_link"}=$Fields{'url'};  
             $groupsearch_db{"pre_${fnum}_title"}=$Fields{'title'};  
             $output.=<<END;  
 <font size='-1'>  
 <input type="checkbox" name="returnvalues" value="SELECT"  
 onClick="javascript:queue($fnum)" />  
 </font>  
 <br />  
 END  
 # <input type="hidden" name="title$fnum" value="$title" />  
 # <input type="hidden" name="url$fnum" value="$url" />  
             $fnum++;  
         }  
         # Render the result into html          # Render the result into html
         $output.= &$viewfunction(%Fields);          $output.= &$viewfunction(%Fields);
         if ($output) {          $output.="</p>\n<hr align='left' width='200' noshade />";
             $output.="<hr align='left' width='200' noshade />";          # Print them out as they come in.
         }  
         $r->print($output);          $r->print($output);
         $r->rflush();          $r->rflush();
     }      }
Line 1683  END Line 1786  END
   
 =pod  =pod
   
   =item &catalogmode_output($title,$url)
   
   Returns html needed for the various catalog modes.  Gets inputs from
   $ENV{'form.catalogmode'}.  Stores data in %groupsearch_db and $fnum 
   (local variable).
   
   =cut
   
   ######################################################################
   ######################################################################
   { 
   my $fnum;
   
   sub catalogmode_output {
       my $output = '';
       my ($title,$url) = @_;
       if ($ENV{'form.catalogmode'} eq 'interactive') {
           $title=~ s/\'/\\'/g; # ' Escape single quotes.
           if ($ENV{'form.catalogmode'} eq 'interactive') {
               $output.=<<END 
   <font size='-1'><INPUT TYPE="button" NAME="returnvalues" VALUE="SELECT"
   onClick="javascript:select_data('$title','$url')">
   </font>
   END
           }
       }
       if ($ENV{'form.catalogmode'} eq 'groupsearch') {
           $fnum+=0;
           $groupsearch_db{"pre_${fnum}_link"}=$url;
           $groupsearch_db{"pre_${fnum}_title"}=$title;
           $output.=<<END;
   <font size='-1'>
   <input type="checkbox" name="returnvalues" value="SELECT"
   onClick="javascript:queue($fnum)" />
   </font>
   END
           $fnum++;
       }
       return $output;
   }
   
   }
   ######################################################################
   ######################################################################
   
   =pod
   
 =item &parse_row  =item &parse_row
   
 Parse a row returned from the database.  Parse a row returned from the database.
Line 1705  sub parse_row { Line 1855  sub parse_row {
         &Apache::loncommon::filedescription($Fields{'mime'});          &Apache::loncommon::filedescription($Fields{'mime'});
     return \%Fields;      return \%Fields;
 }  }
 ######################################################################  
 ######################################################################  
   
 =pod   
   
 =item &output_results()   
   
 Format and output results based on a reply list.  
 There are two windows that this function writes to.  The main search  
 window ("srch") has a listing of the results.  A secondary window ("popwin")  
 gives the status of the network search (time elapsed, number of machines  
 contacted, etc.)  
   
 =cut  
   
 ######################################################################  
 ######################################################################  
 sub output_results {  
 #    &Apache::lonnet::logthis("output_results:".time);  
     my $fnum; # search result counter  
     my ($mode,$r,$replyref,$hidden)=@_;  
     my %rhash=%{$replyref};  
     my $compiledresult='';  
     my $timeremain=300; # (seconds)  
     my $elapsetime=0;  
     my $resultflag=0;  
     my $tflag=1;  
     ##  
     ## Set viewing function  
     ##  
     my $viewfunction = $Views{$ENV{'form.viewselect'}};  
     if (!defined($viewfunction)) {  
         $r->print("Internal Error - Bad view selected.\n");  
         $r->rflush();  
         return;  
     }  
     #  
     # make query information persistent to allow for subsequent revision  
     my $persistent=&make_persistent(\%ENV);  
     #  
     # Begin producing output  
     $r->rflush();  
     #  
     # begin showing the cataloged results  
     my $action = "/adm/searchcat";  
     if ($mode eq 'Basic') {   
         $action .= "?reqinterface=basic";  
     } elsif ($mode eq 'Advanced') {  
         $action .= "?reqinterface=advanced";  
     }  
     $r->print(<<CATALOGCONTROLS);  
 <form name='results' method="post" action="$action">  
 $hidden  
 <input type='hidden' name='acts' value='' />  
 <input type='button' value='Revise search request'  
 onClick='this.form.submit();' />  
 $importbutton  
 $closebutton  
 $persistent  
 <hr />  
 CATALOGCONTROLS  
     #  
     # make the pop-up window for status  
     $r->print(&make_popwin(%rhash));  
     $r->rflush();  
     ##  
     ## Prepare for the main loop below  
     ##  
     my $servercount=0;  
     my $hitcountsum=0;  
     my $servernum=(keys %rhash);  
     my $serversleft=$servernum;  
     ##  
     ## Run until we run out of time or we run out of servers  
     ##  
     while($serversleft && $timeremain) {  
       ##  
       ## %rhash has servers deleted from it as results come in   
       ## (within the foreach loop below).  
       ##  
       foreach my $rkey (sort keys %rhash) {  
 #        &Apache::lonnet::logthis("Server $rkey:".time);  
  $servercount++;  
  $compiledresult='';  
  my $reply=$rhash{$rkey};  
  my @results;  
  if ($reply eq 'con_lost') {  
     &popwin_imgupdate($r,$rkey,"srvbad.gif");  
     $serversleft--;  
             delete $rhash{$rkey};  
  } else {  
             # must do since 'use strict' checks for tainting  
     $reply=~/^([\.\w]+)$/;   
     my $replyfile=$r->dir_config('lonDaemons').'/tmp/'.$1;  
     $reply=~/(.*?)\_/;  
             for (my $counter=0;$counter<2;$counter++) {  
                 if (-e $replyfile && ! -e "$replyfile.end") {  
                     &popwin_imgupdate($r,$rkey,"srvhalf.gif");  
                     &popwin_js($r,'popwin.hc["'.$rkey.'"]='.  
                                '"still transferring..."'.';');  
                 }  
                 # Are we finished transferring data?  
                 if (-e "$replyfile.end") {  
                     $serversleft--;  
                     delete $rhash{$rkey};  
                     if (-s $replyfile) {  
                         &popwin_imgupdate($r,$rkey,"srvgood.gif");  
                         my $fh;  
                         unless ($fh=Apache::File->new($replyfile)){   
                             # Is it really appropriate to die on this error?  
                             $r->print('ERROR: file '.  
                                       $replyfile.' cannot be opened');  
                             return OK;  
                         }  
                         @results=<$fh> if $fh;  
                         my $hits =@results;  
                         &popwin_js($r,'popwin.hc["'.$rkey.'"]='.  
                                    $hits.';');  
                         $hitcountsum+=$hits;  
                         &popwin_js($r,'popwin.document.forms.popremain.'.  
                                    'numhits.value='.$hitcountsum.';');  
                     } else {  
                         &popwin_imgupdate($r,$rkey,"srvempty.gif");  
                         &popwin_js($r,'popwin.hc["'.$rkey.'"]=0;');  
                     }  
                     last;  
                 } # end of if ( -e "$replyfile.end")  
                 last unless $timeremain;  
                 sleep 1;    # wait for daemons to write files?  
                 $timeremain--;  
                 $elapsetime++;  
                 &popwin_js($r,"popwin.document.popremain.".  
                            "elapsetime.value=$elapsetime;");  
     }  
     &popwin_js($r,'popwin.document.whirly.'.  
        'src="/adm/lonIcons/lonanimend.gif";');  
  } # end of if ($reply eq 'con_lost') else statement  
         my %Fields = undef;     # Holds the data to be sent to the various   
                                 # *_view routines.  
         my ($extrashow,$customfields,$customhash) =   
                                     &handle_custom_fields(\@results);  
         my @customfields = @$customfields;  
         my %customhash   = %$customhash;  
  untie %groupsearch_db if (tied %groupsearch_db);  
         #  
  if (! tie(%groupsearch_db,'GDBM_File',$diropendb,&GDBM_WRCREAT,0640)) {  
     $r->print('<html><head></head><body>Unable to tie hash to db '.  
                       'file</body></html>');  
         } else {  
     if ($ENV{'form.launch'} eq '1') {  
  &start_fresh_session();  
     }  
     foreach my $result (@results) {  
  next if $result=~/^custom\=/;  
  chomp $result;  
  next unless $result;  
                 %Fields = &parse_raw_result($result,$rkey);  
                 #  
                 # Check copyright tags and skip results the user cannot use  
                 my (undef,undef,$resdom,$resname) = split('/',$Fields{'url'});  
                 # Check for priv  
                 if (($Fields{'copyright'} eq 'priv') &&   
                     (($ENV{'user.name'} ne $resname) &&  
                      ($ENV{'user.domain'} ne $resdom))) {  
                     next;  
                 }  
                 # Check for domain  
                 if (($Fields{'copyright'} eq 'domain') &&  
                     ($ENV{'user.domain'} ne $resdom)) {  
                     next;  
                 }  
                 #  
  $Fields{'extrashow'}=$extrashow;  
  if ($extrashow) {  
     foreach my $field (@customfields) {  
  my $value='';  
  $value = $1 if ($customhash{$Fields{'url'}}=~/\<{$field}[^\>]*\>(.*?)\<\/{$field}[^\>]*\>/s);  
                         $Fields{'extrashow'}=~s/\<\!\-\- $field \-\-\>/ $value/g;  
                     }  
                 }  
                 $compiledresult.="\n<p>\n";  
                 if ($ENV{'form.catalogmode'} eq 'interactive') {  
                     my $titleesc=$Fields{'title'};  
                     $titleesc=~s/\'/\\'/; # '  
                     $compiledresult.=<<END if ($ENV{'form.catalogmode'} eq 'interactive');  
 <font size='-1'><INPUT TYPE="button" NAME="returnvalues" VALUE="SELECT"  
 onClick="javascript:select_data('$titleesc','$Fields{'url'}')">  
 </font>  
 <br />  
 END  
                 }  
                 if ($ENV{'form.catalogmode'} eq 'groupsearch') {  
     $fnum+=0;  
     $groupsearch_db{"pre_${fnum}_link"}=$Fields{'url'};  
     $groupsearch_db{"pre_${fnum}_title"}=$Fields{'title'};  
     $compiledresult.=<<END;  
 <font size='-1'>  
 <input type="checkbox" name="returnvalues" value="SELECT"  
 onClick="javascript:queue($fnum)" />  
 </font>  
 <br />  
 END  
 # <input type="hidden" name="title$fnum" value="$title" />  
 # <input type="hidden" name="url$fnum" value="$url" />  
                     $fnum++;  
  }  
                 # Render the result into html  
                 $compiledresult.= &$viewfunction(%Fields, hostname => $rkey );  
                 if ($compiledresult or $servercount!=$servernum) {  
                     $compiledresult.="<hr align='left' width='200' noshade />";  
                 }  
             }  
             untie %groupsearch_db;  
         }  
  if ($compiledresult) {  
     $resultflag=1;  
             $r->print($compiledresult);  
  }  
       } # 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('<script type="text/javascript">'.'popwin.close()</script>'.  
               "\n");   
     $r->print("</body>\n</html>\n");  
     $r->rflush();   
     return;  
 }  
   
 ###########################################################  ###########################################################
 ###########################################################  ###########################################################
Line 2214  END Line 2135  END
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
   
 =pod  
   
 =item &make_popwin()  
   
 Returns html with javascript in it to open up the status window.  
   
 =cut  
   
 ######################################################################  
 ######################################################################  
 sub make_popwin {  
     my %rhash = @_;  
     my $servernum=(keys %rhash);  
     my $hcinit;  
     my $grid="'<br />'+\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.="'<a href=\"";  
  $grid.="javascript:opener.displayinfo('+";  
  $grid.="\"'\"+'";  
  $grid.=$sk;  
  my $hc;  
  if ($rhash{$sk} eq 'con_lost') {  
     $hc="BAD CONNECTION ";  
  }  
  else {  
     $hc="'+\"'\"+\"+hc['$sk']+\"+\"'\"+'";  
     $hcinit.="hc[\"$sk\"]=\"not yet connected...\";";  
  }  
  $grid.=" hitcount=".$hc;  
  $grid.=" domain=".$Apache::lonnet::hostdom{$sk};  
  $grid.=" IP=".$Apache::lonnet::hostip{$sk};  
  # '+"'"+'">'+  
  $grid.="'+\"'\"+')\">'+";  
  $grid.="\n";  
  $grid.="'<img border=\"0\" name=\"img_".$Apache::lonnet::hostdom{$sk}.  
             '_'.$sk."\" src=\"/adm/lonIcons/srvnull.gif\" alt=\"".$sk.  
                 "\" /></a>'+\n";  
  $grid.="'<br />'+\n" unless $sn%10;  
         $sn++;  
     }  
     my $result.=<<ENDPOP;  
 <script type="text/javascript">  
     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"/><i>PLEASE BE PATIENT</i>'+  
  '<'+'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();  
 </script>  
 ENDPOP  
     return $result;  
 }  
   
 ######################################################################  
 ######################################################################  
   
 =pod   =pod 
   
 =item Metadata Viewing Functions  =item Metadata Viewing Functions
Line 2490  sub filled { Line 2318  sub filled {
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
 sub output_blank_field_error {  sub output_blank_field_error {
     my ($r)=@_;      my ($r,$closebutton)=@_;
     # make query information persistent to allow for subsequent revision      # make query information persistent to allow for subsequent revision
     my $persistent=&make_persistent(\%ENV);  
   
     $r->print(<<BEGINNING);      $r->print(<<BEGINNING);
 <html>  <html>
 <head>  <head>
Line 2505  BEGINNING Line 2331  BEGINNING
 <img align='right' src='/adm/lonIcons/lonlogos.gif' />  <img align='right' src='/adm/lonIcons/lonlogos.gif' />
 <h1>Search Catalog</h1>  <h1>Search Catalog</h1>
 <form method="post" action="/adm/searchcat">  <form method="post" action="/adm/searchcat">
 $persistent  $hidden_fields
 <input type='button' value='Revise search request'  <input type='button' value='Revise search request'
 onClick='this.form.submit();' />  onClick='this.form.submit();' />
 $closebutton  $closebutton
Line 2531  RESULTS Line 2357  RESULTS
   
 Output a full html page with an error message.  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  =cut
   
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
 sub output_date_error {  sub output_date_error {
     my ($r,$message)=@_;      my ($r,$message,$closebutton)=@_;
     # make query information persistent to allow for subsequent revision      # make query information persistent to allow for subsequent revision
     my $persistent=&make_persistent(\%ENV);  
   
     $r->print(<<RESULTS);      $r->print(<<RESULTS);
 <html>  <html>
 <head>  <head>
Line 2549  sub output_date_error { Line 2379  sub output_date_error {
 <img align='right' src='/adm/lonIcons/lonlogos.gif' />  <img align='right' src='/adm/lonIcons/lonlogos.gif' />
 <h1>Search Catalog</h1>  <h1>Search Catalog</h1>
 <form method="post" action="/adm/searchcat">  <form method="post" action="/adm/searchcat">
 $persistent  $hidden_fields
 <input type='button' value='Revise search request'  <input type='button' value='Revise search request'
 onClick='this.form.submit();' />  onClick='this.form.submit();' />
 $closebutton  $closebutton
Line 2589  sub start_fresh_session { Line 2419  sub start_fresh_session {
     }      }
 }  }
   
 ######################################################################  
 ######################################################################  
   
 =pod   
   
 =item &popwin_js() send javascript to popwin  
   
 =cut  
   
 ######################################################################  
 ######################################################################  
 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");  
 <script type="text/javascript">  
     if (! popwin.closed) {  
  $text  
     }  
 </script>  
 END  
     $r->rflush();  
 }  
   
 ######################################################################  
 ######################################################################  
   
 =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;  1;
   
 __END__  __END__

Removed from v.1.144  
changed lines
  Added in v.1.145


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