Diff for /loncom/interface/lonsearchcat.pm between versions 1.153.2.1 and 1.179

version 1.153.2.1, 2002/09/16 13:05:54 version 1.179, 2003/06/16 19:42:02
Line 74  package Apache::lonsearchcat; Line 74  package Apache::lonsearchcat;
   
 # ------------------------------------------------- modules used by this module  # ------------------------------------------------- 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();
Line 115  that produces it.  Adding a new view typ Line 114  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 $bodytag
   
   LON-CAPA standard body tag, gotten from &Apache::lonnet::bodytag.
   No title, no table, just a <body> tag.
   
 =back   =back 
   
 =cut  =cut
Line 136  my %Views = ("Detailed Citation View" => Line 140  my %Views = ("Detailed Citation View" =>
              "Compact View"           => \&compact_view);               "Compact View"           => \&compact_view);
 my %persistent_db;  my %persistent_db;
 my $hidden_fields;  my $hidden_fields;
   my $bodytag;
   
   #
   # For course search
   #
   my %alreadyseen;
   my $hashtied;
   my %hash;
   my $totalfound;
    
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
   
Line 164  string that holds portions of the screen Line 178  string that holds portions of the screen
 sub handler {  sub handler {
     my $r = shift;      my $r = shift;
     #      #
   
       my $loaderror=&Apache::lonnet::overloaderror($r);
       if ($loaderror) { return $loaderror; }
   
     my $closebutton;  # button that closes the search window       my $closebutton;  # button that closes the search window 
                       # This button is different for the RAT compared to                        # This button is different for the RAT compared to
                       # normal invocation.                        # normal invocation.
Line 180  sub handler { Line 198  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']);
     ##      ##
     ## 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 195  sub handler { Line 214  sub handler {
     ## 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 205  sub handler { Line 223  sub handler {
         ($ENV{'form.launch'} eq '1')) {          ($ENV{'form.launch'} eq '1')) {
         $ENV{'form.persistent_db_id'} = time;          $ENV{'form.persistent_db_id'} = time;
     }      }
       $bodytag=&Apache::loncommon::bodytag(undef,undef,undef,1);
     my $persistent_db_file = "/home/httpd/perl/tmp/".      my $persistent_db_file = "/home/httpd/perl/tmp/".
         &Apache::lonnet::escape($domain).          &Apache::lonnet::escape($domain).
             '_'.&Apache::lonnet::escape($ENV{'user.name'}).              '_'.&Apache::lonnet::escape($ENV{'user.name'}).
Line 217  sub handler { Line 236  sub handler {
             $r->print(<<END);              $r->print(<<END);
 <html>  <html>
 <head><title>LON-CAPA Search Error</title></head>  <head><title>LON-CAPA Search Error</title></head>
 <body>  $bodytag
 We were unable to retrieve data describing your search.  This is a serious  We were unable to retrieve data describing your search.  This is a serious
 error and has been logged.  Please alert your LON-CAPA administrator.  error and has been logged.  Please alert your LON-CAPA administrator.
 </body>  </body>
Line 230  END Line 249  END
     ## Clear out old values from groupsearch database      ## Clear out old values from groupsearch database
     ##      ##
     untie %groupsearch_db if (tied(%groupsearch_db));      untie %groupsearch_db if (tied(%groupsearch_db));
     if (($ENV{'form.launch'} eq '1') &&       if (($ENV{'form.cleargroupsort'} eq '1') || 
         ($ENV{'form.catalogmode'} eq 'groupsearch')) {          (($ENV{'form.launch'} eq '1') && 
            ($ENV{'form.catalogmode'} eq 'groupsearch'))) {
  if (tie(%groupsearch_db,'GDBM_File',$diropendb,&GDBM_WRCREAT(),0640)) {   if (tie(%groupsearch_db,'GDBM_File',$diropendb,&GDBM_WRCREAT(),0640)) {
     &start_fresh_session();      &start_fresh_session();
     untie %groupsearch_db;      untie %groupsearch_db;
               delete($ENV{'form.cleargroupsort'});
  } else {   } else {
     $r->print('<html><head></head><body>Unable to tie hash to db '.              # This is a stupid error to give to the user.  
       'file</body></html>');              # It really tells them nothing.
       $r->print('<html><head></head>'.$bodytag.
                         'Unable to tie hash to db file</body></html>');
     return OK;      return OK;
  }   }
     }      }
Line 322  END Line 345  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 332  END Line 357  END
         if (! defined(&create_results_table())) {          if (! defined(&create_results_table())) {
             $r->print(<<END);              $r->print(<<END);
 <html><head><title>Search Error</title></head>  <html><head><title>Search Error</title></head>
 <body>  $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.
 </body>  </body>
Line 344  END Line 369  END
         if (! &make_form_data_persistent($r,$persistent_db_file)) {          if (! &make_form_data_persistent($r,$persistent_db_file)) {
             $r->print(<<END);              $r->print(<<END);
 <html><head><title>Search Error</title></head>  <html><head><title>Search Error</title></head>
 <body>  $bodytag
 Unable to properly store search information.  The search has been aborted.  Unable to properly store search information.  The search has been aborted.
 </body>  </body>
 </html>  </html>
Line 380  END Line 405  END
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
   
   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
      $hashtied=0;
      undef %alreadyseen;
      %alreadyseen=();
       my $c=$r->connection;
      &tiehash();
      foreach (keys %hash) {
          if ($c->aborted()) { last; }
          if (($_=~/^src\_(.+)$/) && (!$alreadyseen{$hash{$_}})) {
              &checkonthis($r,$hash{$_},0,$hash{'title_'.$1},$fulltext,@allwords);
          }
      }
      &untiehash();
       unless ($totalfound) {
    $r->print('<p>No resources found.</p>');
       }
   # =================================================== Done going through course
       $r->print('</body></html>');
   }
   
   # ---------------------------------------------------------------- tie the hash
   
   sub tiehash {
       $hashtied=0;
       if ($ENV{'request.course.fn'}) {
           if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.".db",
               &GDBM_READER(),0640)) {
                   $hashtied=1;
           }
       }    
   }
   
   sub untiehash {
       if ($hashtied) { untie %hash; }
       $hashtied=0;
   }
   
   # =============================== 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);
          }
       }
   }
   
   ######################################################################
   ######################################################################
   
 =pod   =pod 
   
 =item &print_basic_search_form()   =item &print_basic_search_form() 
Line 393  Returns a scalar which holds html for th Line 523  Returns a scalar which holds html for th
   
 sub print_basic_search_form{  sub print_basic_search_form{
     my ($r,$closebutton) = @_;      my ($r,$closebutton) = @_;
       my $bodytag=&Apache::loncommon::bodytag('Search');
     my $scrout=<<"ENDDOCUMENT";      my $scrout=<<"ENDDOCUMENT";
 <html>  <html>
 <head>  <head>
Line 405  sub print_basic_search_form{ Line 536  sub print_basic_search_form{
     }      }
 </script>  </script>
 </head>  </head>
 <body bgcolor="#FFFFFF">  $bodytag
 <img align='right' src='/adm/lonIcons/lonlogos.gif' />  ENDDOCUMENT
 <h1>Search Catalog</h1>  if (&Apache::lonnet::allowed('bre',$ENV{'request.role.domain'})) {
       $scrout.=(<<ENDDOCUMENT);
   <h1>Catalog Search</h1>
 <form method="post" action="/adm/searchcat">  <form 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
 <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 
 then press SEARCH below.  then press SEARCH below.
Line 424  ENDDOCUMENT Line 556  ENDDOCUMENT
         '&nbsp;';          '&nbsp;';
     my $checkbox = &simplecheckbox('related',$ENV{'form.related'});      my $checkbox = &simplecheckbox('related',$ENV{'form.related'});
     $scrout.=<<END;      $scrout.=<<END;
 </td><td><a href="/adm/searchcat?phase=disp_adv">Advanced Search</a></td></tr>  </td><td><a
   href="/adm/searchcat?phase=disp_adv&catalogmode=$ENV{'form.catalogmode'}&launch=$ENV{'form.launch'}"
   >Advanced Search</a></td></tr>
 <tr><td>$checkbox use related words</td><td></td></tr>  <tr><td>$checkbox use related words</td><td></td></tr>
 </table>  </table>
 </p>  </p>
Line 444  END Line 578  END
 per page.  per page.
 </p>  </p>
 </form>  </form>
   ENDDOCUMENT
       if ($ENV{'request.course.id'}) { $scrout.='<hr />'; }
   }
   if ($ENV{'request.course.id'}) {
       $scrout.=(<<ENDCOURSESEARCH);
   <h1>Course Search</h1>    
   <form method="post" action="/adm/searchcat">
   <input type="hidden" name="phase" value="course_search" />
   $hidden_fields
   <p>
   Enter terms or phrases, then press SEARCH below.
   </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='SEARCH' />
   </p>
   ENDENDCOURSE
   }
       $scrout.=(<<ENDDOCUMENT);
 </body>  </body>
 </html>  </html>
 ENDDOCUMENT  ENDDOCUMENT
Line 477  END Line 640  END
     if (!defined($ENV{'form.viewselect'})) {      if (!defined($ENV{'form.viewselect'})) {
         $ENV{'form.viewselect'} ="Detailed Citation View";          $ENV{'form.viewselect'} ="Detailed Citation View";
     }      }
       my $bodytag=&Apache::loncommon::bodytag('Advanced Catalog Search');
     my $scrout=<<"ENDHEADER";      my $scrout=<<"ENDHEADER";
 <html>  <html>
 <head>  <head>
Line 489  END Line 653  END
     }      }
 </script>  </script>
 </head>  </head>
 <body bgcolor="#FFFFFF">  $bodytag
 <img align='right' src='/adm/lonIcons/lonlogos.gif' />  
 <h1>Advanced Catalog Search</h1>  
 <hr />  
 Enter terms or phrases separated by search operators   Enter terms or phrases separated by search operators 
 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">
Line 529  ENDHEADER Line 690  ENDHEADER
                                              $ENV{'form.abstract'});                                               $ENV{'form.abstract'});
     # 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','mime',      $scrout.=&searchphrasefield('file<br />extension','extension',
                         $ENV{'form.mime'});                          $ENV{'form.extension'});
     $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('publisher<br />owner','owner',      $scrout.=&searchphrasefield('publisher<br />owner','owner',
  $ENV{'form.owner'});   $ENV{'form.owner'});
     $scrout.="</table>\n";      $scrout.="</table>\n";
     $ENV{'form.category'}='any' unless length($ENV{'form.category'});      $ENV{'form.category'}='any' if (! defined($ENV{'form.category'}));
     $scrout.=&selectbox('File Category','category',      $scrout.=&selectbox('File Category','category',
  $ENV{'form.category'},   $ENV{'form.category'},
  'any','Any category',   'any','Any category',
Line 556  ENDHEADER Line 717  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 571  ENDHEADER Line 732  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 618  LASTREVISIONDATEEND Line 779  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 679  sub get_persistent_form_data { Line 840  sub get_persistent_form_data {
                            &GDBM_READER(),0640));                             &GDBM_READER(),0640));
     #      #
     # These make sure we do not get array references printed out as 'values'.      # These make sure we do not get array references printed out as 'values'.
     my %arrays_allowed = ('form.category'=>1,'form.domains'=>1);      my %arrays_allowed = ('form.domains'=>1);
     #      #
     # 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)) {
Line 1121  sub parse_advanced_search { Line 1282  sub parse_advanced_search {
    'lastrevisiondatestart_month','lastrevisiondatestart_day',     'lastrevisiondatestart_month','lastrevisiondatestart_day',
    'lastrevisiondatestart_year','lastrevisiondateend_month',     'lastrevisiondatestart_year','lastrevisiondateend_month',
    'lastrevisiondateend_day','lastrevisiondateend_year',     'lastrevisiondateend_day','lastrevisiondateend_year',
    'notes','abstract','mime','language','owner',     'notes','abstract','extension','language','owner',
    'custommetadata','customshow','category') {     'custommetadata','customshow','category') {
  $ENV{"form.$field"}=~s/[^\w\/\s\(\)\=\-\"\']//g;   $ENV{"form.$field"}=~s/[^\w\/\s\(\)\=\-\"\']//g;
     }      }
Line 1132  sub parse_advanced_search { Line 1293  sub parse_advanced_search {
  $ENV{"form.$_"}=~s/[^\w\/\s\(\)\=\-\"\']//g;   $ENV{"form.$_"}=~s/[^\w\/\s\(\)\=\-\"\']//g;
     }      }
     # Preprocess the category form element.      # Preprocess the category form element.
     $ENV{'form.category'} = 'any' if (ref($ENV{'form.category'}));      $ENV{'form.category'} = 'any' if (! defined($ENV{'form.category'}) ||
     if ($ENV{'form.category'} ne 'any') {                                        ref($ENV{'form.category'}));
         my @extensions = &Apache::loncommon::filecategorytypes      #
             ($ENV{'form.category'});  
         $ENV{'form.mime'} = join ' OR ',@extensions;  
     }  
     # Check to see if enough information was filled in      # Check to see if enough information was filled in
     for my $field ('title','author','subject','keywords','url','version',      for my $field ('title','author','subject','keywords','url','version',
    'notes','abstract','mime','language','owner',     'notes','abstract','category','extension','language',
    'custommetadata') {                     'owner','custommetadata') {
  if (&filled($ENV{"form.$field"})) {   if (&filled($ENV{"form.$field"})) {
     $fillflag++;      $fillflag++;
  }   }
Line 1156  sub parse_advanced_search { Line 1314  sub parse_advanced_search {
     my $font = '<font color="#800000" face="helvetica">';      my $font = '<font color="#800000" face="helvetica">';
     # Evaluate logical expression AND/OR/NOT phrase fields.      # Evaluate logical expression AND/OR/NOT phrase fields.
     foreach my $field ('title','author','subject','notes','abstract','url',      foreach my $field ('title','author','subject','notes','abstract','url',
        'keywords','version','owner','mime') {         'keywords','version','owner') {
  if ($ENV{'form.'.$field}) {   if ($ENV{'form.'.$field}) {
             my $searchphrase = $ENV{'form.'.$field};              my $searchphrase = $ENV{'form.'.$field};
             $pretty_search_string .= $font."$field</font> contains <b>".              $pretty_search_string .= $font."$field</font> contains <b>".
Line 1175  sub parse_advanced_search { Line 1333  sub parse_advanced_search {
     push @queries,&build_SQL_query($field,$searchphrase);      push @queries,&build_SQL_query($field,$searchphrase);
         }          }
     }      }
     # I dislike the hack below.      #
     if ($ENV{'form.category'}) {      # Make the 'mime' from 'form.category' and 'form.extension'
         $ENV{'form.mime'}='';      #
       my $searchphrase;
       if (exists($ENV{'form.category'})    && 
           $ENV{'form.category'} !~ /^\s*$/ &&
           $ENV{'form.category'} ne 'any')     {
           my @extensions = &Apache::loncommon::filecategorytypes
                                                      ($ENV{'form.category'});
           if (scalar(@extensions) > 0) {
               $searchphrase = join(' OR ',@extensions);
           }
       }
       if (exists($ENV{'form.extension'}) && $ENV{'form.extension'} !~ /^\s*$/) {
           $searchphrase .= ' OR ' if (defined($searchphrase));
           my @extensions = split(/,/,$ENV{'form.extension'});
           $searchphrase .= join(' OR ',@extensions);
       }
       if (defined($searchphrase)) {
           push @queries,&build_SQL_query('mime',$searchphrase);
           $pretty_search_string .=$font.'mime</font> contains <b>'.
               $searchphrase.'</b><br />';
     }      }
       #####
     # Evaluate option lists      # Evaluate option lists
     if ($ENV{'form.language'} and $ENV{'form.language'} ne 'any') {      if ($ENV{'form.language'} and $ENV{'form.language'} ne 'any') {
  push @queries,"(language like \"$ENV{'form.language'}\")";   push @queries,"(language like \"$ENV{'form.language'}\")";
Line 1320  sub parse_basic_search { Line 1498  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);
     $pretty_search_string .= "<br />\n";      $pretty_search_string .= "<br />\n";
     return 'select * from metadata where '.$query,$pretty_search_string;      return 'SELECT * FROM metadata WHERE '.$query,$pretty_search_string;
 }  }
   
   
Line 1439  sub recursive_SQL_query_build { Line 1617  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 1674  sub print_sort_form { Line 1848  sub print_sort_form {
 </script>  </script>
 <title>Results</title>  <title>Results</title>
 </head>  </head>
 <body>  $bodytag
 <form name="statusform" action="" method="post">  <form name="statusform" action="" method="post">
 <input type="hidden" name="Queue" value="" />  <input type="hidden" name="Queue" value="" />
 END  END
Line 1719  the following format: Line 1893  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 @Datatypes = 
 ##      ( { name => 'id', 
 my @DataOrder = qw/id title author subject url keywords version notes          type => 'MEDIUMINT',
     abstract mime lang owner copyright creationdate lastrevisiondate hostname/;          restrictions => 'UNSIGNED NOT NULL',
           primary_key  => 'yes',
 my %Datatypes =           auto_inc     => 'yes' },
     ( id        =>{ type         => 'MEDIUMINT',        { name => 'title',     type=>'TEXT'},
                     restrictions => 'UNSIGNED NOT NULL',        { name => 'author',    type=>'TEXT'},
                     primary_key  => 'yes',        { name => 'subject',   type=>'TEXT'},
                     auto_inc     => 'yes'        { name => 'url',       type=>'TEXT', restrictions => 'NOT NULL' },
                     },        { name => 'keywords',  type=>'TEXT'},
       title     =>{ type=>'TEXT'},        { name => 'version',   type=>'TEXT'},
       author    =>{ type=>'TEXT'},        { name => 'notes',     type=>'TEXT'},
       subject   =>{ type=>'TEXT'},        { name => 'abstract',  type=>'TEXT'},
       url       =>{ type=>'TEXT',        { name => 'mime',      type=>'TEXT'},
                     restrictions => 'NOT NULL' },        { name => 'lang',      type=>'TEXT'},
       keywords  =>{ type=>'TEXT'},        { name => 'owner',     type=>'TEXT'},
       version   =>{ type=>'TEXT'},        { name => 'copyright', type=>'TEXT'},
       notes     =>{ type=>'TEXT'},        { name => 'hostname',  type=>'TEXT'},
       abstract  =>{ type=>'TEXT'},  
       mime      =>{ type=>'TEXT'},  
       lang      =>{ type=>'TEXT'},  
       owner     =>{ type=>'TEXT'},  
       copyright =>{ type=>'TEXT'},  
       hostname  =>{ type=>'TEXT'},  
       #--------------------------------------------------        #--------------------------------------------------
       creationdate     =>{ type=>'DATETIME'},        { name => 'creationdate',     type=>'DATETIME'},
       lastrevisiondate =>{ type=>'DATETIME'},        { name => 'lastrevisiondate', type=>'DATETIME'},
       #--------------------------------------------------        #--------------------------------------------------
       );        );
   
Line 1777  Returns: the identifier of the table on Line 1945  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 1861  sub revise_button { Line 2028  sub revise_button {
     $revise_phase = 'disp_adv' if ($ENV{'form.searchmode'} eq 'advanced');      $revise_phase = 'disp_adv' if ($ENV{'form.searchmode'} eq 'advanced');
     my $newloc = '/adm/searchcat'.      my $newloc = '/adm/searchcat'.
         '?persistent_db_id='.$ENV{'form.persistent_db_id'}.          '?persistent_db_id='.$ENV{'form.persistent_db_id'}.
               '&cleargroupsort=1'.
             '&phase='.$revise_phase;              '&phase='.$revise_phase;
     my $result = qq{<input type="button" value="Revise search" name="revise"} .      my $result = qq{<input type="button" value="Revise search" name="revise"} .
         qq{ onClick="parent.location='$newloc';" /> };          qq{ onClick="parent.location='$newloc';" /> };
Line 1892  sub run_search { Line 2060  sub run_search {
     $r->print(<<END);      $r->print(<<END);
 <html>  <html>
 <head><title>Search Status</title></head>  <head><title>Search Status</title></head>
 <body>  $bodytag
 <form name="statusform" action="" method="post">  <form name="statusform" action="" method="post">
 <input type="hidden" name="Queue" value="" />  <input type="hidden" name="Queue" value="" />
 END  END
Line 1962  END Line 2130  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);
     while (($time_remaining > 0) &&       &update_status($r,'contacting '.$Servers_to_contact[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) {
Line 1980  END Line 2149  END
             # left to contact.                # left to contact.  
             sleep(1)              sleep(1)
         }          }
         &update_status($r,'waiting on '.(join(' ',keys(%Server_status))));          #
           if (scalar (keys(%Server_status))) {
               &update_status($r,'waiting on '.(join(' ',keys(%Server_status))));
           }
           #
           # Loop through the servers we have contacted but do not
           # have results from yet, looking for results.
         while (my ($server,$status) = each(%Server_status)) {          while (my ($server,$status) = each(%Server_status)) {
             last if ($connection->aborted());              last if ($connection->aborted());
             if ($status eq 'con_lost') {              if ($status eq 'con_lost') {
Line 2043  END Line 2218  END
         }          }
         last if ($connection->aborted());          last if ($connection->aborted());
         # Finished looping through the servers          # Finished looping through the servers
           $starttime = time if (@Servers_to_contact);
         $time_remaining = $max_time - (time - $starttime) ;          $time_remaining = $max_time - (time - $starttime) ;
         if ($last_time - $time_remaining > 0) {          if ($last_time - $time_remaining > 0) {
             $last_time = $time_remaining;              $last_time = $time_remaining;
Line 2134  sub display_results { Line 2310  sub display_results {
         return;          return;
     }      }
     ##      ##
       ## $checkbox_num is a count of the number of checkboxes output on the 
       ## page this is used only during catalogmode=groupsearch.
       my $checkbox_num = 0;
       ##
     ## Get the catalog controls setup      ## Get the catalog controls setup
     ##      ##
     my $action = "/adm/searchcat?phase=results";      my $action = "/adm/searchcat?phase=results";
Line 2189  sub display_results { Line 2369  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("<h3>There are currently no results.</h3>Please try to reload this page, which will update the display.\n".
                   "</form></body></html>");                    "</form></body></html>");
         return;          return;
     } else {      } else {
Line 2206  sub display_results { Line 2386  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)};
         my $output="<p>\n";          my $output="<p>\n";
         my $prefix=&catalogmode_output($Fields{'title'},$Fields{'url'});          my $prefix=&catalogmode_output($Fields{'title'},$Fields{'url'},
                                          $Fields{'id'},$checkbox_num++);
         # Render the result into html          # Render the result into html
         $output.= &$viewfunction($prefix,%Fields);          $output.= &$viewfunction($prefix,%Fields);
         # Print them out as they come in.          # Print them out as they come in.
Line 2243  sub display_results { Line 2423  sub display_results {
   
 =pod  =pod
   
 =item &catalogmode_output($title,$url)  =item &catalogmode_output($title,$url,$fnum,$checkbox_num)
   
 Returns html needed for the various catalog modes.  Gets inputs from  Returns html needed for the various catalog modes.  Gets inputs from
 $ENV{'form.catalogmode'}.  Stores data in %groupsearch_db and $fnum   $ENV{'form.catalogmode'}.  Stores data in %groupsearch_db.
 (local variable).  
   
 =cut  =cut
   
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
 {   
 my $fnum = 0;  
   
 sub catalogmode_output {  sub catalogmode_output {
     my $output = '';      my $output = '';
     my ($title,$url) = @_;      my ($title,$url,$fnum,$checkbox_num) = @_;
     if ($ENV{'form.catalogmode'} eq 'interactive') {      if ($ENV{'form.catalogmode'} eq 'interactive') {
         $title=~ s/\'/\\\'/g;          $title=~ s/\'/\\\'/g;
         if ($ENV{'form.catalogmode'} eq 'interactive') {          if ($ENV{'form.catalogmode'} eq 'interactive') {
Line 2274  END Line 2450  END
         $output.=<<END;          $output.=<<END;
 <font size='-1'>  <font size='-1'>
 <input type="checkbox" name="returnvalues" value="SELECT"  <input type="checkbox" name="returnvalues" value="SELECT"
 onClick="javascript:queue($fnum)" />  onClick="javascript:queue($checkbox_num,$fnum)" />
 </font>  </font>
 END  END
         $fnum++;  
     }      }
     return $output;      return $output;
 }  }
   
 }  
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
   
Line 2300  sub parse_row { Line 2473  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{'lang'});
Line 2530  SCRIPT Line 2703  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(val) {      function queue(checkbox_num,val) {
         if (document.forms.results.returnvalues[val].checked) {          if (document.forms.results.returnvalues[checkbox_num].checked) {
             parent.statusframe.document.forms.statusform.elements.Queue.value +='1a'+val+'b';              parent.statusframe.document.forms.statusform.elements.Queue.value +='1a'+val+'b';
         } else {          } else {
             parent.statusframe.document.forms.statusform.elements.Queue.value +='0a'+val+'b';              parent.statusframe.document.forms.statusform.elements.Queue.value +='0a'+val+'b';
Line 2546  SCRIPT Line 2719  SCRIPT
 SCRIPT  SCRIPT
     $result.=<<END;      $result.=<<END;
 </head>  </head>
   $bodytag
 <form name="results" method="post" action="" >  <form name="results" method="post" action="" >
 <input type="hidden" name="Queue" value="" />  <input type="hidden" name="Queue" value="" />
 $importbutton  $importbutton
Line 2558  END Line 2732  END
 sub search_status_header {  sub search_status_header {
     return <<ENDSTATUS;      return <<ENDSTATUS;
 <html><head><title>Search Status</title></head>  <html><head><title>Search Status</title></head>
 <body>  $bodytag
 <h3>Search Status</h3>  <h3>Search Status</h3>
 Sending search request to LON-CAPA servers.<br />  Sending search request to LON-CAPA servers.<br />
 ENDSTATUS  ENDSTATUS
Line 2585  sub print_frames_interface { Line 2759  sub print_frames_interface {
 <head>  <head>
 <script>  <script>
 var targetwin = opener;  var targetwin = opener;
   var queue = '';
 </script>  </script>
 <title>LON-CAPA Digital Library Search Results</title>  <title>LON-CAPA Digital Library Search Results</title>
 </head>  </head>
Line 2830  sub output_blank_field_error { Line 3005  sub output_blank_field_error {
 BEGINNING  BEGINNING
     $r->print(<<RESULTS);      $r->print(<<RESULTS);
 </head>  </head>
 <body bgcolor="#ffffff">  $bodytag
 <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">
Line 2877  sub output_date_error { Line 3052  sub output_date_error {
 <head>  <head>
 <title>The LearningOnline Network with CAPA</title>  <title>The LearningOnline Network with CAPA</title>
 </head>  </head>
 <body bgcolor="#ffffff">  $bodytag
 <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">
Line 2923  sub start_fresh_session { Line 3098  sub start_fresh_session {
   
 1;  1;
   
   sub cleanup {
       if (tied(%groupsearch_db)) {
    &Apache::lonnet::logthis('Cleanup searchcat: 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.153.2.1  
changed lines
  Added in v.1.179


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