Diff for /loncom/interface/lonsearchcat.pm between versions 1.282 and 1.363

version 1.282, 2007/03/12 17:09:23 version 1.363, 2025/03/19 15:30:29
Line 52  search (on a server basis) is displayed Line 52  search (on a server basis) is displayed
   
 =head1 Internals  =head1 Internals
   
 =over 4  
   
 =cut  =cut
   
 ###############################################################################  ###############################################################################
Line 78  use HTML::Entities(); Line 76  use HTML::Entities();
 use Parse::RecDescent;  use Parse::RecDescent;
 use Apache::lonnavmaps;  use Apache::lonnavmaps;
 use Apache::lonindexer();  use Apache::lonindexer();
   use Apache::lonwishlist();
 use LONCAPA;  use LONCAPA;
   use Time::HiRes qw(sleep);
   
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
Line 118  sub handler { Line 118  sub handler {
                       # This is set and used in &handler() and is also used in                         # This is set and used in &handler() and is also used in 
                       # &output_results().                        # &output_results().
   
     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
Line 138  sub handler { Line 136  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','titleelement','area']);                'cleargroupsort','titleelement','area','inhibitmenu']);
     ##      ##
     ## 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 146  sub handler { Line 144  sub handler {
     ##     this once, so the pause indicator is deleted      ##     this once, so the pause indicator is deleted
     ##      ##
     if (exists($env{'form.pause'})) {      if (exists($env{'form.pause'})) {
         sleep(1);          sleep(0.1);
         delete($env{'form.pause'});          delete($env{'form.pause'});
     }      }
     ##      ##
     ## Initialize global variables      ## Initialize global variables
     ##      ##
     my $domain  = $r->dir_config('lonDefDomain');      my $domain  = $r->dir_config('lonDefDomain');
     $diropendb= "/home/httpd/perl/tmp/".      my $temp_file_dir = LONCAPA::tempdir();
       $diropendb= $temp_file_dir .
         "$env{'user.domain'}_$env{'user.name'}_sel_res.db";          "$env{'user.domain'}_$env{'user.name'}_sel_res.db";
     #      #
     # set the name of the persistent database      # set the name of the persistent database
Line 164  sub handler { Line 163  sub handler {
         $env{'form.persistent_db_id'} = time;          $env{'form.persistent_db_id'} = time;
     }      }
   
     my $persistent_db_file = "/home/httpd/perl/tmp/".      my $persistent_db_file = $temp_file_dir .
         &escape($domain).          &escape($domain).
             '_'.&escape($env{'user.name'}).              '_'.&escape($env{'user.name'}).
                 '_'.$env{'form.persistent_db_id'}.'_persistent_search.db';                  '_'.$env{'form.persistent_db_id'}.'_persistent_search.db';
     ##      ##
     &Apache::lonhtmlcommon::clear_breadcrumbs();      &Apache::lonhtmlcommon::clear_breadcrumbs();
   
     my @allowed_searches = ('portfolio');      my $crumb_text;
     if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'})) {      my @allowed_searches;
       if ($env{'form.catalogmode'} eq 'import') {
           $env{'form.area'} = 'res';
           $crumb_text = 'Content Library Search';
       } else {
           push(@allowed_searches,'portfolio');
       }
       if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'}) eq 'F') {
         push(@allowed_searches,'res');          push(@allowed_searches,'res');
     }       } else {
     if (exists($env{'request.course.id'}) && $env{'request.course.id'} ne '') {          unless ($env{'form.catalogmode'} eq 'import') {
         push(@allowed_searches,'course');              $env{'form.area'} = 'portfolio';
               $crumb_text = 'Portfolio Search';
           }
     }      }
     my $crumb_text = 'Portfolio Search';      if (@allowed_searches ==2) {
     if (@allowed_searches == 3) {         unless (($env{'form.area'} eq 'portfolio') || ($env{'form.area'} eq 'res')) {
         $crumb_text = 'Course, Portfolio and Catalog Search';             delete($env{'form.area'});
     } elsif (@allowed_searches ==2) {         }
         if (grep(/^res$/,@allowed_searches)) {         $crumb_text = 'Portfolio and Content Library Search'; 
             $crumb_text = 'Portfolio and Catalog Search';       }
         } elsif (grep(/^course$/,@allowed_searches)) {      my $target = '_top';
             $crumb_text = 'Portfolio and Course Search';      if ((($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) ||
           (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'} eq '_self'))) {
           if ($env{'form.phase'} =~ /^(sort|run_search)$/) {
               $target = '_parent';
           } else {
               $target = '_self';
         }          }
     }      }
     &Apache::lonhtmlcommon::add_breadcrumb      &Apache::lonhtmlcommon::add_breadcrumb
        ({href=>'/adm/searchcat?'.         ({href=>'/adm/searchcat?'.
                'catalogmode='.$env{'form.catalogmode'}.         &Apache::loncommon::inhibit_menu_check().
                '&launch='.$env{'form.launch'}.                 '&catalogmode='.$env{'form.catalogmode'}.
                '&mode='.$env{'form.mode'},                 '&launch='.$env{'form.launch'}.
                  '&mode='.$env{'form.mode'}.
                  '&area='.$env{'form.area'},
               text=>"$crumb_text",                text=>"$crumb_text",
               target=>'_top',                target=>$target,
               bug=>'Searching',});                bug=>'Searching',});
     #      #
     if ($env{'form.phase'} !~ m/(basic|adv|course)_search/) {      if ($env{'form.phase'} !~ m/(basic|adv|course)_search/) {
Line 203  sub handler { Line 218  sub handler {
                 &Apache::lonnet::logthis('lonsearchcat:'.                  &Apache::lonnet::logthis('lonsearchcat:'.
                                          'Unable to recover data from '.                                           'Unable to recover data from '.
                                          $persistent_db_file);                                           $persistent_db_file);
  my $msg =                  my $msg =
     'We were unable to retrieve data describing your search. '.                      &mt('We were unable to retrieve data describing your search.').
     'This is a serious error and has been logged. '.                      ' '.&mt('This is a serious error and has been logged.').
     'Please alert your LON-CAPA administrator.';                      '<br />'.
  &Apache::loncommon::simple_error_page($r,'Search Error',                      &mt('Please alert your LON-CAPA administrator.');
       $msg);                  &Apache::loncommon::simple_error_page(
                       $r,'Search Error',
                       $msg,
                       {'no_auto_mt_msg' => 1});
  return OK;   return OK;
             }              }
         }          }
Line 258  sub handler { Line 276  sub handler {
     if (exists($env{'form.area'})) {      if (exists($env{'form.area'})) {
         $hidden_fields .= &hidden_field('area');          $hidden_fields .= &hidden_field('area');
     }      }
       if (exists($env{'form.inhibitmenu'})) {
           $hidden_fields .= &hidden_field('inhibitmenu');
       }
     ##      ##
     ## Configure dynamic components of interface      ## Configure dynamic components of interface
     ##      ##
     if ($env{'form.catalogmode'} eq 'interactive') {      if ($env{'form.catalogmode'} eq 'interactive') {
         $closebutton="<input type='button' name='close' value='CLOSE' ";          $closebutton="<input type='button' name='close' value='".&mt('Close')."' ";
         if ($env{'form.phase'} =~ /(results|run_search)/) {          if ($env{'form.phase'} =~ /(results|run_search)/) {
     $closebutton .="onClick='parent.close()'";              $closebutton .="onclick='parent.close()'";
         } else {          } else {
             $closebutton .="onClick='self.close()'";              $closebutton .="onclick='self.close()'";
         }          }
         $closebutton .=">\n";          $closebutton .=" />\n";
     } elsif ($env{'form.catalogmode'} eq 'import') {      } elsif ($env{'form.catalogmode'} eq 'import') {
         $closebutton="<input type='button' name='close' value='CLOSE' ";          $closebutton="<input type='button' name='close' value='".&mt('Close')."' ";
         if ($env{'form.phase'} =~ /(results|run_search)/) {          if ($env{'form.phase'} =~ /(results|run_search)/) {
     $closebutton .="onClick='parent.close()'";              $closebutton .="onclick='parent.close()'";
         } else {          } else {
             $closebutton .="onClick='self.close()'";              $closebutton .="onclick='self.close()'";
         }          }
         $closebutton .= ">";          $closebutton .= " />";
           my $txt_import = &mt('IMPORT');
         $importbutton=<<END;          $importbutton=<<END;
 <input type='button' name='import' value='IMPORT'  <input type='button' name='import' value='$txt_import'
 onClick='javascript:select_group()'>  onclick='javascript:select_group()' />
 END  END
     } else {      } else {
         $closebutton = '';          $closebutton = '';
Line 298  END Line 320  END
     if ($env{'form.phase'} eq 'adv_search' ||      if ($env{'form.phase'} eq 'adv_search' ||
         $env{'form.phase'} eq 'disp_adv') {          $env{'form.phase'} eq 'disp_adv') {
         $env{'form.searchmode'} = 'advanced';          $env{'form.searchmode'} = 'advanced';
     } elsif ($env{'form.phase'} eq 'course_search') {  
         $env{'form.searchmode'} = 'course_search';  
     }      }
     #      #
     if ($env{'form.searchmode'} eq 'advanced') {      if ($env{'form.searchmode'} eq 'advanced') {
         my $srchtype = 'Catalog';          my $srchtype = 'Content Library';
         if ($env{'form.area'} eq 'portfolio') {          if ($env{'form.area'} eq 'portfolio') {
             $srchtype = 'Portfolio';              $srchtype = 'Portfolio';
         }          }
         &Apache::lonhtmlcommon::add_breadcrumb          &Apache::lonhtmlcommon::add_breadcrumb
             ({href=>'/adm/searchcat?phase=disp_adv&'.              ({href=>'/adm/searchcat?'.&Apache::loncommon::inhibit_menu_check().
                   'catalogmode='.$env{'form.catalogmode'}.                    '&amp;phase=disp_adv'.
                   '&launch='.$env{'form.launch'}.                    '&amp;catalogmode='.$env{'form.catalogmode'}.
                   '&mode='.$env{'form.mode'},                    '&amp;launch='.$env{'form.launch'}.
                     '&amp;mode='.$env{'form.mode'}.
                     '&amp;area='.$env{'form.area'},
                   text=>"Advanced $srchtype Search",                    text=>"Advanced $srchtype Search",
                   bug=>'Searching',});                    bug=>'Searching',});
     } elsif ($env{'form.searchmode'} eq 'course search') {      } elsif (($env{'form.phase'} eq 'results') ||
                ($env{'form.phase'} =~ /^(sort|run_search)$/)) {
         &Apache::lonhtmlcommon::add_breadcrumb          &Apache::lonhtmlcommon::add_breadcrumb
             ({href=>'/adm/searchcat?phase=disp_adv&'.              ({href=>'/adm/searchcat?'.&Apache::loncommon::inhibit_menu_check().
                   'catalogmode='.$env{'form.catalogmode'}.                '&amp;phase=disp_adv'.
                   '&launch='.$env{'form.launch'}.                '&amp;catalogmode='.$env{'form.catalogmode'}.
                   '&mode='.$env{'form.mode'},                '&amp;launch='.$env{'form.launch'}.
                   text=>"Course Search",                '&amp;mode='.$env{'form.mode'}.
                   bug=>'Searching',});                '&amp;area='.$env{'form.area'}.
                 '&amp;searchmode='.$env{'form.searchmode'},
                 text=>"Search Results",
                 bug=>'Searching',});
     }      }
     ##      ##
     ## Switch on the phase      ## Switch on the phase
Line 334  END Line 360  END
         &display_results($r,$importbutton,$closebutton,$diropendb,          &display_results($r,$importbutton,$closebutton,$diropendb,
                          $env{'form.area'});                           $env{'form.area'});
     } elsif ($env{'form.phase'} =~ /^(sort|run_search)$/) {      } elsif ($env{'form.phase'} =~ /^(sort|run_search)$/) {
         my ($query,$customquery,$customshow,$libraries,$pretty_string) =          my ($query,$customquery,$customshow,$libraries,$pretty_string,$domainsref) =
             &get_persistent_data($persistent_db_file,              &get_persistent_data($persistent_db_file,
                  ['query','customquery','customshow',                   ['query','customquery','customshow',
                   'libraries','pretty_string']);                    'libraries','pretty_string','domains']);
         if ($env{'form.phase'} eq 'sort') {          if ($env{'form.phase'} eq 'sort') {
             &print_sort_form($r,$pretty_string);              &print_sort_form($r,$pretty_string,$target);
         } elsif ($env{'form.phase'} eq 'run_search') {          } elsif ($env{'form.phase'} eq 'run_search') {
             &run_search($r,$query,$customquery,$customshow,              &run_search($r,$query,$customquery,$customshow,
                         $libraries,$pretty_string,$env{'form.area'});                          $libraries,$pretty_string,$env{'form.area'},$domainsref,$target);
         }          }
     } 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')) {
         #          #
         # We are running a search, try to parse it          # We are running a search, try to parse it
         my ($query,$customquery,$customshow,$libraries) =           my ($query,$customquery,$customshow,$libraries,$domains) = 
             (undef,undef,undef,undef);              (undef,undef,undef,undef,undef);
         my $pretty_string;          my $pretty_string;
         if ($env{'form.phase'} eq 'basic_search') {          if ($env{'form.phase'} eq 'basic_search') {
             ($query,$pretty_string,$libraries) =               ($query,$pretty_string,$libraries,$domains) = 
                 &parse_basic_search($r,$closebutton,$hidden_fields);                  &parse_basic_search($r,$closebutton,$hidden_fields);
             return OK if (! defined($query));              return OK if (! defined($query));
             &make_persistent({ basicexp => $env{'form.basicexp'}},              &make_persistent({ basicexp => $env{'form.basicexp'}},
                              $persistent_db_file);                               $persistent_db_file);
         } else {                      # Advanced search          } else {                      # Advanced search
             ($query,$customquery,$customshow,$libraries,$pretty_string)               ($query,$customquery,$customshow,$libraries,$pretty_string,$domains) 
                 = &parse_advanced_search($r,$closebutton,$hidden_fields);                  = &parse_advanced_search($r,$closebutton,$hidden_fields);
             return OK if (! defined($query));              return OK if (! defined($query));
         }          }
Line 368  END Line 392  END
                            customquery => $customquery,                             customquery => $customquery,
                            customshow => $customshow,                             customshow => $customshow,
                            libraries => $libraries,                             libraries => $libraries,
                            pretty_string => $pretty_string },                             pretty_string => $pretty_string,
                              domains => $domains },
                          $persistent_db_file);                           $persistent_db_file);
         #          #
         # Set up table          # Set up table
Line 379  END Line 404  END
                                      $errorstring);                                       $errorstring);
   
     my $msg =       my $msg = 
  'Unable to create table in which to store search results. '.   'Unable to create table in which to save search results. '.
  'The search has been aborted.';   'The search has been aborted.';
     &Apache::loncommon::simple_error_page($r,'Search Error',      &Apache::loncommon::simple_error_page($r,'Search Error',
   $msg);    $msg);
Line 388  END Line 413  END
         delete($env{'form.launch'});          delete($env{'form.launch'});
         if (! &make_form_data_persistent($r,$persistent_db_file)) {          if (! &make_form_data_persistent($r,$persistent_db_file)) {
     my $msg=      my $msg=
  'Unable to properly store search information. '.   'Unable to properly save search information. '.
  'The search has been aborted.';   'The search has been aborted.';
     &Apache::loncommon::simple_error_page($r,'Search Error',      &Apache::loncommon::simple_error_page($r,'Search Error',
   $msg);    $msg);
Line 402  END Line 427  END
         }          }
     }      }
     return OK;      return OK;
 }   }
   
 #  #
 # The mechanism used to store values away and retrieve them does not  # The mechanism used to store values away and retrieve them does not
Line 440  sub hidden_field { Line 465  sub hidden_field {
     return '<input type="hidden" name="'.$name.'" value="'.$value.'" />'.$/;      return '<input type="hidden" name="'.$name.'" value="'.$value.'" />'.$/;
 }  }
   
 ######################################################################  sub start_search_tabs {
 ######################################################################      my $area;
 ##      my %lt = &Apache::lonlocal::texthash (
 ##   Course Search                                res => 'Content Library Search',
 ##                                portfolio => 'Portfolio Search',
 ######################################################################      );
 ######################################################################      my $output = '<ul class="LC_TabContentBigger" id="main">';
 {   # Scope the course search to avoid global variables      if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'}) eq 'F') {
 #          unless ($env{'form.area'} eq 'portfolio') {
 # Variables For course search              $area = 'res';
 my %alreadyseen;          }
 my %hash;          $output .= "\n".'<li'.($area eq 'res'?' class="active"':'').
 my $totalfound;                     '><a href="/adm/searchcat?area=res&amp;catalogmode='.$env{'form.catalogmode'}.'">'.
                      '<b>&nbsp;&nbsp;&nbsp;&nbsp;'.$lt{'res'}.
 sub make_symb {                     '&nbsp;&nbsp;&nbsp;&nbsp;</b></a></li>';
     my ($id)=@_;          unless ($env{'form.catalogmode'}) {
     my ($mapid,$resid)=split(/\./,$id);              $output .= '<li'.($area ne 'res'?' class="active"':'').
     my $map=$hash{'map_id_'.$mapid};                         '><a href="/adm/searchcat?area=portfolio"><b>&nbsp;&nbsp;&nbsp;&nbsp;'.$lt{'portfolio'}.
     my $res=$hash{'src_'.$id};                         '&nbsp;&nbsp;&nbsp;&nbsp;</b></a></li></ul>';
     my $symb=&Apache::lonnet::encode_symb($map,$resid,$res);  
     return $symb;  
 }  
   
 sub course_search {  
     my $r=shift;  
     my $pretty_search_string = '<b>'.$env{'form.courseexp'}.'</b>';  
     my $search_string = $env{'form.courseexp'};  
     my @New_Words;  
     undef(%alreadyseen);  
     if ($env{'form.crsrelated'}) {  
         ($search_string,@New_Words) = &related_version($env{'form.courseexp'});  
         if (@New_Words) {  
             $pretty_search_string .= ' '.&mt("with related words").": <b>@New_Words</b>.";  
         } else {  
             $pretty_search_string .= ' '.&mt('with no related words').".";  
         }  
     }  
     my $fulltext=$env{'form.crsfulltext'};  
     my $discuss=$env{'form.crsdiscuss'};  
     my @allwords=($search_string,@New_Words);  
     $totalfound=0;  
     $r->print(&Apache::loncommon::start_page('Course Search').  
       '<hr /><center><font size="+2" face="arial">'.  
       $pretty_search_string.'</font></center>'.  
       '<hr /><b>'.&mt('Course content').':</b><br />');  
     $r->rflush();  
 # ======================================================= Go through the course  
     my $c=$r->connection;  
     if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.".db",  
             &GDBM_READER(),0640)) {  
         foreach (sort(keys(%hash))) {  
             if ($c->aborted()) { last; }  
             if (($_=~/^src\_(.+)$/)) {  
  if ($hash{'randomout_'.$1} & !$env{'request.role.adv'}) {  
     next;   
  }  
  my $symb=&make_symb($1);  
                 &checkonthis($r,$1,$hash{$_},0,&Apache::lonnet::gettitle($symb),  
      $fulltext,$symb,@allwords);  
             }  
         }  
         untie(%hash);  
     }  
     unless ($totalfound) {  
  $r->print('<p>'.&mt('No matches found in resources').'.</p>');  
     }  
   
 # Check discussions if requested  
     if ($discuss) {  
         my $totaldiscussions = 0;  
         $r->print('<br /><br /><b>'.&mt('Discussion postings').':</b><br />');   
         my $navmap = Apache::lonnavmaps::navmap->new();  
         my @allres=$navmap->retrieveResources();  
         my %discussiontime = &Apache::lonnet::dump('discussiontimes',  
                                $env{'course.'.$env{'request.course.id'}.'.domain'},  
                                $env{'course.'.$env{'request.course.id'}.'.num'});  
         foreach my $resource (@allres) {  
             my $result = '';  
             my $applies = 0;  
             my $symb = $resource->symb();  
             my $ressymb = $symb;  
             if ($symb =~ m#(___adm/$LONCAPA::domain_re/$LONCAPA::username_re)/(\d+)/bulletinboard$#) {  
                 $ressymb = 'bulletin___'.$2.$1.'/'.$2.'/bulletinboard';  
                 unless ($ressymb =~ m#bulletin___\d+___adm/wrapper#) {  
                     $ressymb=~s#(bulletin___\d+___)#$1adm/wrapper/#;  
                 }  
             }  
             if (defined($discussiontime{$ressymb})) {   
                 my %contrib = &Apache::lonnet::restore($ressymb,$env{'request.course.id'},  
                      $env{'course.'.$env{'request.course.id'}.'.domain'},  
                      $env{'course.'.$env{'request.course.id'}.'.num'});  
                 if ($contrib{'version'}) {  
                     for (my $id=1;$id<=$contrib{'version'};$id++) {  
                         unless (($contrib{'hidden'}=~/\.$id\./) || ($contrib{'deleted'}=~/\.$id\./)) {   
                             if ($contrib{$id.':subject'}) {  
                                 $result .= $contrib{$id.':subject'};  
                             }  
                             if ($contrib{$id.':message'}) {  
                                 $result .= $contrib{$id.':message'};  
                             }  
                             if ($contrib{$id,':attachmenturl'}) {  
                                 if ($contrib{$id,':attachmenturl'} =~ m-/([^/]+)$-) {  
                                     $result .= $1;  
                                 }  
                             }  
                             $applies = &checkwords($result,$applies,@allwords);  
                         }  
                     }  
                 }  
             }  
 # Does this discussion apply?  
             if ($applies) {  
                 my ($map,$ind,$url)=&Apache::lonnet::decode_symb($ressymb);  
                 my $disctype = &mt('resource');  
                 if ($url =~ m#/bulletinboard$#) {  
                     if ($url =~m#^adm/wrapper/adm/.*/bulletinboard$#) {  
                         $url =~s#^adm/wrapper##;  
                     }  
                     $disctype = &mt('bulletin board');  
                 } else {  
                     $url = '/res/'.$url;  
                 }  
                 if ($url =~ /\?/) {  
                     $url .= '&symb=';  
                 } else {  
                     $url .= '?symb=';  
                 }  
                 $url .= &escape($resource->symb());  
                 my $title = $resource->compTitle();  
                 $r->print('<br /><a href="'.$url.'" target="cat">'.  
                      ($title?$title:$url).'</a>&nbsp;&nbsp;-&nbsp;'.$disctype.'<br />');  
                 $totaldiscussions++;  
             } else {  
                 $r->print(' .');  
             }  
         }  
         unless ($totaldiscussions) {  
             $r->print('<p>'.&mt('No matches found in postings').'.</p>');  
         }  
     }  
    
 # =================================================== Done going through course  
     $r->print(&Apache::loncommon::end_page());  
 }  
   
 # =============================== This pulls up a resource and its dependencies  
   
 sub checkonthis {  
     my ($r,$id,$url,$level,$title,$fulltext,$symb,@allwords)=@_;  
     $alreadyseen{$id}=1;  
     if (&Apache::loncommon::connection_aborted($r)) { return; }  
     $r->rflush();  
       
     my $result=$title.' ';  
     if ($env{'request.role.adv'} || !$hash{'encrypted_'.$id}) {  
  $result.=&Apache::lonnet::metadata($url,'title').' '.  
     &Apache::lonnet::metadata($url,'subject').' '.  
     &Apache::lonnet::metadata($url,'abstract').' '.  
     &Apache::lonnet::metadata($url,'keywords');  
     }  
     my ($extension)=($url=~/\.(\w+)$/);  
     if (&Apache::loncommon::fileembstyle($extension) eq 'ssi' &&  
  ($url) && ($fulltext)) {  
  $result.=&Apache::lonnet::ssi_body($url.'?symb='.&escape($symb));  
     }  
     $result=~s/\s+/ /gs;  
     my $applies = 0;  
     $applies = &checkwords($result,$applies,@allwords);  
 # Does this resource apply?  
     if ($applies) {  
        $r->print('<br />');  
        for (my $i=0;$i<=$level*5;$i++) {  
            $r->print('&nbsp;');  
        }  
        my $href=$url;  
        if ($hash{'encrypted_'.$id} && !$env{'request.role.adv'}) {  
    $href=&Apache::lonenc::encrypted($href)  
        .'?symb='.&Apache::lonenc::encrypted($symb);  
        } else {  
    $href.='?symb='.&escape($symb);  
        }  
        $r->print('<a href="'.$href.'" 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{$id})) {   
           &checkonthis($r,$id,$_,$level+1,'',$fulltext,undef,@allwords);  
        }  
     }  
 }  
   
 sub checkwords {  
     my ($result,$applies,@allwords) = @_;  
     foreach (@allwords) {  
         if ($_=~/\w/) {  
             if ($result=~/$_/si) {  
                 $applies++;  
             }  
         }          }
     }      } else {
     return $applies;          $area = 'portfolio';
           $output .= "\n".'<li class="active">'.
                      '<a href="/adm/searchcat?area=portfolio"><b>&nbsp;&nbsp;&nbsp;&nbsp;'.$lt{'portfolio'}.
                      '&nbsp;&nbsp;&nbsp;&nbsp;</b></a></li></ul>';
       }
       $output .= '<div class="LC_Box" style="clear:both;margin:0;">'.
                  '<div id="maincoursedoc" style="margin:0 0;padding:0 0;">'.
                  '<div class="LC_ContentBox" id="mainCourseDocuments" style="display: block;">';
       return $output;
 }  }
   
 sub untiehash {  sub end_search_tabs {
     if (tied(%hash)) {      return '</div></div></div>';
         untie(%hash);  
     }  
 }  }
   
 } # End of course search scoping  
   
   
 ######################################################################  
 ######################################################################  ######################################################################
   
 =pod   =pod
   
   =over 4
    
 =item &print_basic_search_form()   =item &print_basic_search_form() 
   
 Prints the form for the basic search.  Sorry the name is so cryptic.  Prints the form for the basic search.  Sorry the name is so cryptic.
Line 674  Prints the form for the basic search.  S Line 517  Prints the form for the basic search.  S
 ######################################################################  ######################################################################
 sub print_basic_search_form {  sub print_basic_search_form {
     my ($r,$closebutton,$hidden_fields) = @_;      my ($r,$closebutton,$hidden_fields) = @_;
       my %lt = &Apache::lonlocal::texthash (
                                 res => 'Content Library Search',
                                 portfolio => 'Portfolio Search',
       );
     my $result = ($env{'form.catalogmode'} ne 'import');      my $result = ($env{'form.catalogmode'} ne 'import');
       my $area;
     my $bread_crumb =      my $bread_crumb =
         &Apache::lonhtmlcommon::breadcrumbs('Searching','Search_Basic',          &Apache::lonhtmlcommon::breadcrumbs('Searching','Search_Basic',
     $env{'form.catalogmode'} ne 'import');      $env{'form.catalogmode'} ne 'import');
     my $scrout = &Apache::loncommon::start_page('Search').$bread_crumb;      my $scrout = &Apache::loncommon::start_page('Content Library').$bread_crumb.
 # Search form for resource space                    '<div class="LC_landmark" role="main">'."\n".
     if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'})) {                   &start_search_tabs();
         $scrout .= &setup_basic_search($r,'res',$hidden_fields,$closebutton);      if (&Apache::lonnet::allowed('bre',$env{'request.role.domain'}) eq 'F') {
         $scrout .= '<hr /><br />';          if ($env{'form.area'} eq 'portfolio') {
     }  
 # Search form for accessible portfolio files  # Search form for accessible portfolio files
     $scrout.= &setup_basic_search($r,'portfolio',$hidden_fields,$closebutton);              $scrout .= &setup_basic_search($r,'portfolio',$hidden_fields,$closebutton);
     if ($env{'request.course.id'}) {          } else {
  my %lt=&Apache::lonlocal::texthash('srch' => 'Search',  # Search form for resource space
                                            'header' => 'Course Search',              $scrout .= &setup_basic_search($r,'res',$hidden_fields,$closebutton);
  'note' => 'Enter terms or phrases, then press "Search" below',          }
  'use' => 'use related words',      } else {
  'full' =>'fulltext search (time consuming)',  # Search form for accessible portfolio files
          'disc' => 'search discussion postings (resources and bulletin boards)',          $scrout .= &setup_basic_search($r,'portfolio',$hidden_fields,$closebutton);
    );  
         $scrout.=(<<ENDCOURSESEARCH);  
 <form name="loncapa_search" method="post" action="/adm/searchcat">  
 <center>  
 <hr />  
 <h1>$lt{'header'}</h1>      
 <input type="hidden" name="phase" value="course_search" />  
 $hidden_fields  
 <p>  
 $lt{'note'}.  
 </p>  
 <p>  
 <table>  
 <tr><td>  
 ENDCOURSESEARCH  
         $scrout.='&nbsp;'.  
             &Apache::lonhtmlcommon::textbox('courseexp',  
                                   $env{'form.courseexp'},40);  
         my $crscheckbox =   
             &Apache::lonhtmlcommon::checkbox('crsfulltext',  
                                    $env{'form.crsfulltext'});  
         my $relcheckbox =   
             &Apache::lonhtmlcommon::checkbox('crsrelated',  
    $env{'form.crsrelated'});  
         my $discheckbox =   
             &Apache::lonhtmlcommon::checkbox('crsdiscuss',  
                                    $env{'form.crsrelated'});  
         $scrout.=(<<ENDENDCOURSE);  
 </td></tr>  
 <tr><td><label>$relcheckbox $lt{'use'}</label></td><td></td></tr>  
 <tr><td><label>$crscheckbox $lt{'full'}</label></td><td></td></tr>  
 <tr><td><label>$discheckbox $lt{'disc'}</label></td><td></td></tr>  
 </table><p>  
 &nbsp;<input type="submit" name="coursesubmit" value='$lt{'srch'}' />  
 </p>  
 </center>  
 </form>  
 ENDENDCOURSE  
     }      }
     $scrout .= &Apache::loncommon::end_page();      $scrout .= &end_search_tabs().&Apache::loncommon::end_page();
     $r->print($scrout);      $r->print($scrout);
     return;      return;
 }  }
Line 741  sub setup_basic_search { Line 550  sub setup_basic_search {
     my ($r,$area,$hidden_fields,$closebutton) = @_;      my ($r,$area,$hidden_fields,$closebutton) = @_;
     # Define interface components      # Define interface components
     my %lt = &Apache::lonlocal::texthash (      my %lt = &Apache::lonlocal::texthash (
                               res => 'LON-CAPA Catalog Search',                                res => 'Content Library Search',
                               portfolio => 'Portfolio Search',                                portfolio => 'Portfolio Search',
     );      );
     my ($userelatedwords,$onlysearchdomain,$inclext,$adv_search_link,$scrout);      my ($userelatedwords,$onlysearchdomain,$inclext,$adv_search_link,$scrout);
     $userelatedwords = '<label>'.&mt('[_1] use related words',  
       &Apache::lonhtmlcommon::checkbox('related',$env{'form.related'},'related')).      $userelatedwords = '<label>'
                        '</label>';                        .&Apache::lonhtmlcommon::checkbox(
     $onlysearchdomain = '<label>'.&mt('[_1] only search domain [_2]',                             'related',
       &Apache::lonhtmlcommon::checkbox('domains',$env{'form.domains'},                             $env{'form.related'},
                                        $r->dir_config('lonDefDomain')),                             'related')
       $r->dir_config('lonDefDomain')).                        .' '
                         '</label>';                       .&mt('use related words')
                        .'</label>';
   
       my $anydom = 1;
     if ($area eq 'res') {      if ($area eq 'res') {
         $inclext= '<label>'.&mt('[_1] include external resources',          unless (&Apache::lonnet::allowed('bre','/res/') eq 'F') {
              &Apache::lonhtmlcommon::checkbox('inclext',$env{'form.inclext'})).              $anydom = 0;
                   '</label>';          }
     }      }
       my $singledom;
       my ($disabled,$checked);
       if ($anydom) {
          $singledom = $r->dir_config('lonDefDomain');
          if ($env{'form.domains'} eq $singledom) {
              $checked = 1;
          }
       } else {
          $singledom = $env{'user.domain'};
          $disabled = ' disabled="disabled"';
          $checked = 1; 
       }
       $onlysearchdomain = '<label>'
                          .&Apache::lonhtmlcommon::checkbox(
                              'domains',$checked,
                              $singledom,$disabled)
                          .' '
                          .&mt('only search domain [_1]'
                                  ,'<b>'.$singledom.'</b>')
                          .'</label>';
   
     $adv_search_link = '<a href="/adm/searchcat?'.      $adv_search_link = '<a href="/adm/searchcat?'.
                        'phase=disp_adv&'.                 &Apache::loncommon::inhibit_menu_check().
                        'catalogmode='.$env{'form.catalogmode'}.         '&amp;phase=disp_adv'.
                        '&launch='.$env{'form.launch'}.                         '&amp;catalogmode='.$env{'form.catalogmode'}.
                        '&mode='.$env{'form.mode'}.                         '&amp;launch='.$env{'form.launch'}.
                        '&area='.$area.                         '&amp;mode='.$env{'form.mode'}.
                          '&amp;area='.$area.
                          '&amp;form='.$env{'form.form'}.
                          '&amp;titleelement='.$env{'form.titleelement'}.
                          '&amp;element='.$env{'form.element'}.
                        '">'.&mt('Advanced Search').'</a>';                         '">'.&mt('Advanced Search').'</a>';
     #      #
     $scrout.='<form name="loncapa_search" method="post" '.      $scrout.='<form name="loncapa_search" method="post" '.
Line 774  sub setup_basic_search { Line 611  sub setup_basic_search {
                  $scrout .= '<input type="hidden" name="area" value="'.$area.'" />';                   $scrout .= '<input type="hidden" name="area" value="'.$area.'" />';
              }               }
     #      #
     $scrout .= '<center>'.$/;      $scrout .= '<div class="LC_floatleft">'.
 #    if ($env{'request.course.id'}) {                 '<label>'.
         $scrout .= '<h1>'.$lt{$area}.'</h1>';                 &Apache::lonhtmlcommon::textbox('basicexp',
 #    } else {                                                 $env{'form.basicexp'},50).
         # No need to tell them they are searching                 '<br />'.
 #        $scrout.= ('<br />'x2);                 '<span class="LC_fontsize_medium">'.&searchhelp().'</span></label></div>'.
 #    }                 '<div class="LC_floatleft" style="text-align: left;">'.
     $scrout.='<table>'.                 '<span class="LC_nobreak">'.('&nbsp;'x3).$adv_search_link.'</span>'.'<br />'.
              '<tr><td align="center" valign="top">'.                 '<span class="LC_nobreak">'.('&nbsp;'x1).$userelatedwords.'</span>'.'<br />'.
              &Apache::lonhtmlcommon::textbox('basicexp',                 '<span class="LC_nobreak">'.('&nbsp;'x1).$onlysearchdomain.'</span>'.'<br />'.
                                              $env{'form.basicexp'},50).                 '<span class="LC_nobreak">'.('&nbsp;'x1).$inclext.'</span>'.'<br />'.
              '<br />'.                 '</div><br clear="both" />'.$/;
             '<font size="-1">'.&searchhelp().'</font>'.'</td>'.      #
             '<td><font size="-1">'.      $scrout .= '<div><p>'
             '<nobr>'.('&nbsp;'x3).$adv_search_link.'</nobr>'.'<br />'.                .&viewoptions()
             '<nobr>'.('&nbsp;'x1).$userelatedwords.'</nobr>'.'<br />'.                .'</p>'
             '<nobr>'.('&nbsp;'x1).$onlysearchdomain.'</nobr>'.'<br />'.                .'<p>'
             '<nobr>'.('&nbsp;'x1).$inclext.'</nobr>'.'<br />'.                .'<input type="submit" name="basicsubmit" '
              '</font></td>'.                .'value="'.&mt('Search').'" />'
             '</tr>'.$/;                .' '
     #                .$closebutton
     $scrout .= '<tr><td align="center" colspan="2">'.                .'</p></div>';
                '<font size="-1">'.      #
                '<input type="submit" name="basicsubmit" '.      $scrout .= '</form>';
                'value="'.&mt('Search').'" />'.  
                ('&nbsp;'x2).$closebutton.('&nbsp;'x2). &viewoptions().  
                '</font>'.  
                '</td></tr>'.$/;  
     $scrout .= '</table>'.$/.'</center>'.'</form>';  
     return $scrout;      return $scrout;
 }   } 
   
Line 828  sub print_advanced_search_form{ Line 660  sub print_advanced_search_form{
        'reset' => 'Reset',         'reset' => 'Reset',
        'help' => 'Help');         'help' => 'Help');
     my $advanced_buttons=<<"END";      my $advanced_buttons=<<"END";
   <p>
 <input type="submit" name="advancedsubmit" value='$lt{"srch"}' />  <input type="submit" name="advancedsubmit" value='$lt{"srch"}' />
 <input type="reset" name="reset" value='$lt{"reset"}' />  <input type="reset" name="reset" value='$lt{"reset"}' />
 $closebutton  $closebutton
   </p>
 END  END
     my $srchtype = 'Catalog';      my $srchtype = 'Content Library';
     my $jscript;      my $jscript;
     if ($env{'form.area'} eq 'portfolio') {      if ($env{'form.area'} eq 'portfolio') {
         $srchtype = 'Portfolio';          $srchtype = 'Portfolio';
         $jscript = '<script type="text/javascript">          $jscript = '<script type="text/javascript">
   // <![CDATA[
 function additional_metadata() {  function additional_metadata() {
     if (document.advsearch.newfield.checked) {      if (document.advsearch.newfield.checked) {
         document.advsearch.phase.value = "disp_adv";          document.advsearch.phase.value = "disp_adv";
Line 844  function additional_metadata() { Line 679  function additional_metadata() {
         document.advsearch.submit();          document.advsearch.submit();
     }      }
 }  }
   // ]]>
 </script>';  </script>';
     }      }
     my $scrout= &Apache::loncommon::start_page("Advanced $srchtype Search",      my $scrout= &Apache::loncommon::start_page("Advanced $srchtype Search",
                                                $jscript);                                                 $jscript);
     $scrout .= <<"ENDHEADER";      $scrout .= $bread_crumb.'<div class="LC_landmark" role="main">'."\n".
 $bread_crumb                 &start_search_tabs();
 <form method="post" action="/adm/searchcat" name="advsearch">  
 <p>      $scrout .= '<form method="post" action="/adm/searchcat" name="advsearch">'
 $advanced_buttons                .$hidden_fields 
 ENDHEADER                .'<input type="hidden" name="phase" value="adv_search" />';
     $scrout.=('&nbsp;'x2).&viewoptions().'</p>'.$hidden_fields.   
         '<input type="hidden" name="phase" value="adv_search" />';      $scrout .= '<fieldset>'."\n"
                 .'<legend>'.&mt('Display Options').'</legend>'."\n"
                 .&viewoptions()
                 .'</fieldset>';
   
       $scrout .= $advanced_buttons;
   
       $scrout .= &Apache::lonhtmlcommon::start_pick_box();
   
     my %fields=&Apache::lonmeta::fieldnames();      my %fields=&Apache::lonmeta::fieldnames();
     #  
     $scrout .= '<h3>'.&mt('Standard [_1] Metadata',$srchtype).'</h3>';      # Standard Metadata
     $scrout .= "<table>\n";      $scrout .= &Apache::lonhtmlcommon::row_headline()
     $scrout .= '<tr><td>&nbsp;</td><td colspan="2"><font size="-1">'.                .'<h2 class="LC_heading_2">'.&mt("Standard $srchtype Metadata").'</h2>'
         ('&nbsp;'x2).&searchhelp()."</font></td></tr>\n";                .&searchhelp()
                 .&Apache::lonhtmlcommon::row_closure();
     my %related_word_search =       my %related_word_search = 
         ('title'    => 1,          ('title'    => 1,
          'author'   => 0,           'author'   => 0,
Line 873  ENDHEADER Line 718  ENDHEADER
          'abstract' => 1,           'abstract' => 1,
          'standards'=> 1,           'standards'=> 1,
          'mime'     => 1,           'mime'     => 1,
  'subject'  => 1,           'subject'  => 1,
          );           );
     #      #
     foreach my $field ('title','author','subject','owner','authorspace',      foreach my $field ('title','author','subject','owner','authorspace',
        'modifyinguser','keywords','notes','abstract',                         'modifyinguser','keywords','notes','abstract',
        'standards','mime') {                         'standards','mime') {
  $scrout.='<tr><td align="right">'.&titlefield($fields{$field}).'</td><td>'.          $scrout .= &Apache::lonhtmlcommon::row_title('<label for="'.$field.'">'.
     &Apache::lonmeta::prettyinput($field,                                                       &titlefield($fields{$field}).'</label>')
                                           $env{'form.'.$field},                    .&Apache::lonmeta::prettyinput($field,
                                             $env{'form.'.$field},'',
                                           $field,                                            $field,
                                           'advsearch',                                            'advsearch',
   $related_word_search{$field},                                            $related_word_search{$field},
                                           '</td><td align="left">',                                            '&nbsp;&nbsp;',
                                           $env{'form.'.$field.'_related'},                                            $env{'form.'.$field.'_related'},
                                           50);                                            50);
         if ($related_word_search{$field}) {          if ($related_word_search{$field}) {
             $scrout .= 'related words';              $scrout .= '<label for="'.$field.'_related">'.&mt('related words').'</label>';
         } else {          } else {
             $scrout .= '</td><td>&nbsp;';              $scrout .= '';
         }          }
         $scrout .= '</td></tr>'.$/;          $scrout .= &Apache::lonhtmlcommon::row_closure();
     }      }
     foreach my $field ('lowestgradelevel','highestgradelevel') {      foreach my $field ('lowestgradelevel','highestgradelevel') {
  $scrout.='<tr>'.          $scrout .= &Apache::lonhtmlcommon::row_title('<label for="'.$field.'">'.
             '<td align="right">'.&titlefield($fields{$field}).'</td>'.                                                       &titlefield($fields{$field}).'</label>')
             '<td colspan="2">'.                    .&Apache::lonmeta::prettyinput($field,
     &Apache::lonmeta::prettyinput($field,                                            $env{'form.'.$field},'',
                                           $env{'form.'.$field},  
                                           $field,                                            $field,
                                           'advsearch',                                            'advsearch',
   0).                                            0)
                                           '</td></tr>'.$/;                    .&Apache::lonhtmlcommon::row_closure();
     }      }
     $scrout.='<tr><td align="right">'.  
  &titlefield(&mt('MIME Type Category')).'</td><td colspan="2">'.       $scrout .= &Apache::lonhtmlcommon::row_title('<label for="category">'.
     &Apache::loncommon::filecategoryselect('category',                                                   &titlefield(&mt('MIME Type Category')).'</label>')
    $env{'form.category'}).                .&Apache::loncommon::filecategoryselect('category',
     '</td></tr>'.$/;                     $env{'form.category'},'category')
     $scrout.='<tr><td align="right" valign="top">'.                .&Apache::lonhtmlcommon::row_closure();
  &titlefield(&mt('Domains')).'</td><td colspan="2">'.   
     &Apache::loncommon::domain_select('domains',      my $anydomain = 1;
    $env{'form.domains'},1).      if ($env{'form.area'} ne 'portfolio') {
    '<br /><label>';          unless (&Apache::lonnet::allowed('bre','/res/')) {
             if ($env{'form.area'} ne 'portfolio') {              $anydomain = 0; 
                 $scrout .= &mt('[_1] include external resources',          }
                            &Apache::lonhtmlcommon::checkbox      }
                            ('inclext',$env{'form.inclext'})).'</label>'  
             }      $scrout .= &Apache::lonhtmlcommon::row_title('<label for="domains">'.
      $scrout .= '</td></tr>'.$/;                                                   &titlefield(&mt('Domains')).'</label>');
     #      if ($anydomain) {
           my $defdom = &Apache::lonnet::default_login_domain();
           my ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('shared',$defdom);
           $scrout .= &Apache::loncommon::domain_select('domains',
                      $env{'form.domains'},1,$trusted,$untrusted,'domains');
       } else {
           $scrout .= &Apache::loncommon::select_dom_form($env{'user.domain'},
                                                          'domains','','','',
                                                          [$env{'user.domain'}],'',1,'domains');
       }
       $scrout .= &Apache::lonhtmlcommon::row_closure();
   
     # Misc metadata      # Misc metadata
     if ($env{'form.area'} ne 'portfolio') {      if ($env{'form.area'} ne 'portfolio') {
         $scrout.='<tr><td align="right" valign="top">'.          $scrout .= &Apache::lonhtmlcommon::row_title('<label for="copyright">'.
          &titlefield(&mt('Copyright/Distribution')).                                                       &titlefield(&mt('Copyright/Distribution')).'</label>')
                  '</td><td colspan="2">'.                    .&Apache::lonmeta::selectbox('copyright',
                  &Apache::lonmeta::selectbox('copyright',                                               $env{'form.copyright'},'',
                                              $env{'form.copyright'},                                               'copyright',
                                 \&Apache::loncommon::copyrightdescription,                                  \&Apache::loncommon::copyrightdescription,
                                        ( undef,                                         ( undef,
                                         &Apache::loncommon::copyrightids)                                          &Apache::loncommon::copyrightids)
                                 ).'</td></tr>'.$/;                                  )
                     .&Apache::lonhtmlcommon::row_closure();
     }      }
     $scrout.='<tr><td align="right" valign="top">'.  
  &titlefield(&mt('Language')).'</td><td colspan="2">'.      $scrout .= &Apache::lonhtmlcommon::row_title('<label for="language">'.
         &Apache::lonmeta::selectbox('language',                                                   &titlefield(&mt('Language')).'</label>')
                                     $env{'form.language'},                .&Apache::lonmeta::selectbox('language',
                                       $env{'form.language'},'','language',
                                     \&Apache::loncommon::languagedescription,                                      \&Apache::loncommon::languagedescription,
                                     ('any',&Apache::loncommon::languageids)                                      ('any',&Apache::loncommon::languageids)
                                     ).'</td></tr>';                                      )
     $scrout .= "</table>\n";                .&Apache::lonhtmlcommon::row_closure();
   
           
       # Portfolio Metadata
     if ($env{'form.area'} eq 'portfolio') {      if ($env{'form.area'} eq 'portfolio') {
         # Added fields          # Added fields
         my $curnumadd = $env{'form.numaddedfields'};          my $curnumadd = $env{'form.numaddedfields'};
         if ($curnumadd eq '') {          if ($curnumadd eq '') {
             $curnumadd = 1;              $curnumadd = 1;
         }          }
         $scrout .= '<h3>'.&mt('Custom Metadata fields').'</h3>';          my $customlabel = &mt('Text box description');
         $scrout .= "<table>\n";          $scrout .= &Apache::lonhtmlcommon::row_headline()
         $scrout .= '<tr><td>&nbsp;</td><td align="center">'.                    .'<h3>'.&mt('Custom Metadata fields').'</h3>'
                    &mt('Field Name').'</td>'.'<td align="center">'.                    .&Apache::lonhtmlcommon::row_closure()
                    &mt('Field Value(s)').'</td></tr>';                    .&Apache::lonhtmlcommon::row_title('<span class="LC_visually_hidden">'.$customlabel.'</span>',
                                                        '','','',1)
                     .&mt('Field Name').' | '.&mt('Field Value(s)')
                     .&Apache::lonhtmlcommon::row_closure();
   
         for (my $j=0; $j<$curnumadd; $j++) {          for (my $j=0; $j<$curnumadd; $j++) {
             my $num = $j+1;              my $num = $j+1;
             $scrout .= '<tr><td>'.&mt('Custom metadata [_1]: ',$num).              my $namelabel = &mt('name of custom metadata field [_1]',$num);
                        '</td><td align="center">'.              my $valuelabel = &mt('value of custom metadata field [_1]',$num);
                        '<input type="text" name="addedfield_'.$j.              $scrout .= &Apache::lonhtmlcommon::row_title(&mt('Custom metadata [_1]',$num))
                        '" size="10" value="'.$env{'form.addedfield_'.$j}.                        .'<input type="text" id="addedfield_'.$j.'"'
                        '" /></td>'.                        .' name="addedfield_'.$j.'" size="10"'
                        '<td align="center"><input type="text" '.                        .' value="'.$env{'form.addedfield_'.$j}.'" aria-label="'.$namelabel.'" />'
                        'name="addedvalues_'.$j.'" size="15" value="'.                        .' '
                        $env{'form.addedvalues_'.$j}.'" /></td></tr>';                        .'<input type="text" '
         }                        .'name="addedvalues_'.$j.'" size="15"'
         $scrout .= '<tr><td align="left" colspan="3"><label>'.                        .' value="'.$env{'form.addedvalues_'.$j}.'" aria-label="'.$valuelabel.'" />'
                    '<input type="checkbox" name="newfield" '.                        .&Apache::lonhtmlcommon::row_closure();
                    'value="1" onclick="javascript:additional_metadata()" />'.          }
                    &mt('Another custom field/value pair?').'</label>'.          my $addcustomlabel = &mt('Add metadata field option');
                    '<input type="hidden" name="numaddedfields" value="'.          $scrout .= &Apache::lonhtmlcommon::row_title('<span class="LC_visually_hidden">'.$addcustomlabel.'</span>',
                    $curnumadd.'" /></td></tr></table>';                                                       '','','',1)
     } else {                    .'<label>'
                     .'<input type="checkbox" name="newfield"'
                     .' value="1" onclick="javascript:additional_metadata()" />'
                     .&mt('Another custom field/value pair?').'</label>'
                     .'<input type="hidden" name="numaddedfields"'
                     .' value="'.$curnumadd.'" />'
                     .&Apache::lonhtmlcommon::row_closure();
   } else {
         #          #
         # Dynamic metadata          # Dynamic metadata
         $scrout .= '<h3>'.&mt('Problem Statistics').'</h3>';          my $statslabel = &mt('Text box description');
         $scrout .= "<table>\n";          $scrout .= &Apache::lonhtmlcommon::row_headline()
         $scrout .= '<tr><td>&nbsp;</td><td align="center">'.                    .'<h3>'.&mt('Problem Statistics').'</h3>'
                    &mt('Minimum').'</td>'.'<td align="center">'.                    .&Apache::lonhtmlcommon::row_closure();
                    &mt('Maximum').'</td></tr>'."\n";          $scrout .= &Apache::lonhtmlcommon::row_title('<span class="LC_visually_hidden">'.$statslabel.'</span>',
                                                        '','','',1)
                     .&mt('Minimum').' | '.&mt('Maximum')
                     .&Apache::lonhtmlcommon::row_closure();
         foreach my $statistic           foreach my $statistic 
             ({ name=>'count',              ({ name=>'count',
                description=>'Network-wide number of accesses (hits)',},                 description=>'Network-wide number of accesses (hits)',
                  minlabel => 'minimum hit count',
                  maxlabel => 'maximum hit count'},
              { name=>'stdno',               { name=>'stdno',
                description=>                 description=>
                'Total number of students who have worked on this problem',},                 'Statistics calculated for number of students',
                  minlabel => 'minimum number of students in calculation',
                  maxlabel => 'maximum number of students in calculation'},
              { name => 'avetries',               { name => 'avetries',
                description=>'Average number of tries till solved',},                 description=>'Average number of tries till solved',
                  minlabel => 'minimum average tries till solved',
                  maxlabel => 'maximum average tries till solved'},
              { name => 'difficulty',               { name => 'difficulty',
                description=>'Degree of difficulty',},                 description=>'Degree of difficulty',
                  minlabel => 'minimum degree of difficulty',
                  maxlabel => 'maximum degree of difficulty'},
              { name => 'disc',               { name => 'disc',
                description=>'Degree of discrimination'}) {                 description=>'Degree of discrimination',
               $scrout .= '<tr><td align="right">'.                 minlabel => 'minimum degree of discrimination',
                          &titlefield(&mt($statistic->{'description'})).                 maxlabel => 'maximum degree of discrimination'}) {
                          '</td><td align="center">'.                $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt($statistic->{'description'})))
                          '<input type="text" name="'.$statistic->{'name'}.                          .'<input type="text" name="'.$statistic->{'name'}
                          '_min" value="" size="6" /></td><td align="center">'.                          .'_min" value="" size="6" aria-label="'.&mt($statistic->{'minlabel'}).'" />'
                          '<input type="text" name="'.$statistic->{'name'}.                          .' '
                          '_max" value="" size="6" /></td></tr>'.$/;                          .'<input type="text" name="'.$statistic->{'name'}
         }                          .'_max" value="" size="6" aria-label="'.&mt($statistic->{'maxlabel'}).'" />'
         $scrout .= "</table>\n";                          .&Apache::lonhtmlcommon::row_closure();
         $scrout .= '<h3>'.&mt('Evaluation Data').'</h3>';          }
         $scrout .= "<table>\n";          my $evallabel = &mt('Text box description');
         $scrout .= '<tr><td>&nbsp;</td><td align="center">'.          $scrout .= &Apache::lonhtmlcommon::row_headline()
                    &mt('Minimum').'</td>'.'<td align="center">'.                    .'<h3>'.&mt('Evaluation Data').'</h3>'
                    &mt('Maximum').'</td></tr>'."\n";                    .&Apache::lonhtmlcommon::row_closure();
           $scrout .= &Apache::lonhtmlcommon::row_title('<span class="LC_visually_hidden">'.$evallabel.'</span>',
                                                        '','','',1)
                     .&mt('Minimum').' | '.&mt('Maximum')
                     .&Apache::lonhtmlcommon::row_closure();
         foreach my $evaluation          foreach my $evaluation
             ( { name => 'clear',              ( { name => 'clear',
                 description => 'Material presented in clear way'},                  description => 'Material presented in clear way',
                   minlabel => 'minimum score: clarity',
                   maxlabel => 'maximum score: clarity'},
               { name =>'depth',                { name =>'depth',
                 description => 'Material covered with sufficient depth'},                  description => 'Material covered with sufficient depth',
                   minlabel => 'minimum score: coverage depth',
                   maxlabel => 'maximum score: coverage depth'},
               { name => 'helpful',                { name => 'helpful',
                 description => 'Material is helpful'},                  description => 'Material is helpful',
                   minlabel => 'minimum score: content helpful',
                   maxlabel => 'maximum score: content helpful'},
               { name => 'correct',                { name => 'correct',
                 description => 'Material appears to be correct'},                  description => 'Material appears to be correct',
                   minlabel => 'minimum score: correctness',
                   maxlabel => 'maximum score: correctness'},
               { name => 'technical',                { name => 'technical',
                 description => 'Resource is technically correct'}){                  description => 'Resource is technically correct',
             $scrout .= '<tr><td align="right">'.                  minlabel => 'minimum score: technical correctness',
                        &titlefield(&mt($evaluation->{'description'})).                  maxlabel => 'maximum score: technical correctness'}) {
                        '</td><td align="center">'.              $scrout .= &Apache::lonhtmlcommon::row_title(&titlefield(&mt($evaluation->{'description'})))
                        '<input type="text" name="'.                        .'<input type="text" name="'
                        $evaluation->{'name'}.'_min" value="" size="6" />'.                        .$evaluation->{'name'}.'_min" value="" size="6" aria-label="'.&mt($evaluation->{'minlabel'}).'" />'
                        '</td><td align="center"><input type="text" name="'.                        .' '
                        $evaluation->{'name'}.'_max" value="" size="6" />'.                        .'<input type="text" name="'
                        '</td></tr>'.$/;                        .$evaluation->{'name'}.'_max" value="" size="6" aria-label="'.&mt($evaluation->{'maxlabel'}).'" />'
                         .&Apache::lonhtmlcommon::row_closure();
         }          }
         $scrout .= "</table>\n";  
     }      }
     #      #
     # Creation/Modification date limits      # Creation/Modification date limits
     $scrout .= '<h3>'.&mt('Creation and Modification dates').'</h3>';      my $dateslabel = &mt('Text box description');
     $scrout .= "\n<table>\n";      $scrout .= &Apache::lonhtmlcommon::row_headline()
                 .'<h3>'.&mt('Creation and Modification dates').'</h3>'
                 .&Apache::lonhtmlcommon::row_closure();
       $scrout .= &Apache::lonhtmlcommon::row_title('<span class="LC_visually_hidden">'.$dateslabel.'</span>',
                                                    '','','',1)
                 .&mt('Month[_1]Day[_2]Year','&nbsp;'x14,'&nbsp;'x6)
                 .&Apache::lonhtmlcommon::row_closure();
   
     my $cafter =       my $cafter = 
         &Apache::lonhtmlcommon::date_setter('advsearch',         # formname          &Apache::lonhtmlcommon::date_setter('advsearch',         # formname
                                             'creationdate1', # fieldname                                              'creationdate1', # fieldname
Line 1052  ENDHEADER Line 950  ENDHEADER
                                             '',          # state                                              '',          # state
                                             1,           # no_hh_mm_ss                                              1,           # no_hh_mm_ss
                                             );                                              );
     $scrout .= &mt('<tr><td align="right">Created between</td>'.      $scrout .= &Apache::lonhtmlcommon::row_title(&mt('Created between'))
                    '<td>[_1]</td></tr>'.                .$cafter
                    '<tr><td align="right">and </td>'.                .&Apache::lonhtmlcommon::row_closure(1)
                    '<td>[_2]</td></tr>',$cafter,$cbefore);                .&Apache::lonhtmlcommon::row_title(&mt('and'))
                 .$cbefore
                 .&Apache::lonhtmlcommon::row_closure();
   
     my $lafter =       my $lafter = 
         &Apache::lonhtmlcommon::date_setter('advsearch',          &Apache::lonhtmlcommon::date_setter('advsearch',
                                             'revisiondate1',                                               'revisiondate1', 
Line 1074  ENDHEADER Line 975  ENDHEADER
                                             '',          # state                                              '',          # state
                                             1,           # no_hh_mm_ss                                              1,           # no_hh_mm_ss
                                             );                                              );
     $scrout .= &mt('<tr><td align="right">Last modified between </td>'.      $scrout .= &Apache::lonhtmlcommon::row_title(&mt('Last modified between'))
                    '<td>[_1]</td></tr>'.                .$lafter
                    '<tr><td align="right">and</td>'.                .&Apache::lonhtmlcommon::row_closure(1)
                    '<td>[_2]</td></tr>',$lafter,$lbefore);                .&Apache::lonhtmlcommon::row_title(&mt('and'))
     $scrout.="</table>\n";                .$lbefore
     $scrout.=<<ENDDOCUMENT;                .&Apache::lonhtmlcommon::row_closure(1); # Last row of total pick_box
 $advanced_buttons  
 </form>      $scrout .= &Apache::lonhtmlcommon::end_pick_box();
 ENDDOCUMENT  
     $scrout .= &Apache::loncommon::end_page();      $scrout .= $advanced_buttons
                 .'</form>';
   
       $scrout .= &end_search_tabs().'</div>'.&Apache::loncommon::end_page();
     $r->print($scrout);      $r->print($scrout);
     return;      return;
 }  }
Line 1156  sub viewoptions { Line 1060  sub viewoptions {
     if (! defined($env{'form.viewselect'})) {       if (! defined($env{'form.viewselect'})) { 
         $env{'form.viewselect'}='detailed';           $env{'form.viewselect'}='detailed'; 
     }      }
     $scrout.=&Apache::lonmeta::selectbox('viewselect',      $scrout .= '<span class="LC_nobreak"><label>'
  $env{'form.viewselect'},                .&mt('Type:').' '
  \&viewoptiontext,                .&Apache::lonmeta::selectbox('viewselect',
  sort(keys(%Views)));                     $env{'form.viewselect'},'','',
     $scrout.= '&nbsp;&nbsp;';                     \&viewoptiontext,
                      sort(keys(%Views)))
                 .'</label></span>';
     my $countselect = &Apache::lonmeta::selectbox('show',      my $countselect = &Apache::lonmeta::selectbox('show',
                                                   $env{'form.show'},                                                    $env{'form.show'},'','',
                                                   undef,                                                    undef,
                                                   (10,20,50,100,1000,10000));                                                    (10,20,50,100,1000,10000));
     $scrout .= ('&nbsp;'x2).&mt('[_1] Records per Page',$countselect).      $scrout .= ' <span class="LC_nobreak"><label>'
         '</nobr>'.$/;                .&mt('Records per Page:').' '.$countselect
                 .'</label></span>'.$/;
     return $scrout;      return $scrout;
 }  }
   
Line 1257  Outputs: array of values.  Returns undef Line 1164  Outputs: array of values.  Returns undef
   
 This function is the reverse of &make_persistent();  This function is the reverse of &make_persistent();
 Retrieve persistent data from %persistent_db.  Retrieved items will have their  Retrieve persistent data from %persistent_db.  Retrieved items will have their
 values unescaped.  If the item contains commas (before unescaping), the  values unescaped.  If the item is 'domains; then the returned
 returned value will be an array pointer.   value will be a hash pointer.  Otherwise, if the item contains
   commas (before unescaping), the returned value will be an array pointer.
   
 =cut  =cut
   
Line 1276  sub get_persistent_data { Line 1184  sub get_persistent_data {
             push @Values, undef;              push @Values, undef;
             next;              next;
         }          }
         my @values = map {           if ($name eq 'domains') {
             &unescape($_);              my %valueshash;
         } split(',',$persistent_db{$name});              my @items= map { &unescape($_); } split(',',$persistent_db{$name});
         if (@values <= 1) {              foreach my $item (@items) {
             push @Values,$values[0];                  if ($item =~ /=/) {
                       my ($key,$val) = map { &unescape($_); } split(/=/,$item);
                       $valueshash{$key} = $val;
                   }
               }
               push(@Values,\%valueshash);
         } else {          } else {
             push @Values,\@values;              my @values = map { 
                   &unescape($_);
               } split(',',$persistent_db{$name});
               if (@values <= 1) {
                   push @Values,$values[0];
               } else {
                   push @Values,\@values;
               }
         }          }
     }      }
     untie (%persistent_db);      untie (%persistent_db);
Line 1300  Inputs: Hash of values to save, filename Line 1220  Inputs: Hash of values to save, filename
   
 Store variables away to the %persistent_db.  Store variables away to the %persistent_db.
 Values will be escaped.  Values that are array pointers will have their  Values will be escaped.  Values that are array pointers will have their
 elements escaped and concatenated in a comma separated string.    elements escaped and concatenated in a comma separated string. Values 
   that are hash pointers will have their keys and values escaped and 
   concatenated in a comma separated string.
   
 =cut  =cut
   
Line 1312  sub make_persistent { Line 1234  sub make_persistent {
     return undef if (! tie(%persistent_db,'GDBM_File',      return undef if (! tie(%persistent_db,'GDBM_File',
                            $filename,&GDBM_WRCREAT(),0640));                             $filename,&GDBM_WRCREAT(),0640));
     foreach my $name (keys(%save)) {      foreach my $name (keys(%save)) {
         my @values = (ref($save{$name}) ? @{$save{$name}} : ($save{$name}));          my @values=();
         # We handle array references, but not recursively.          if (ref($save{$name}) eq 'ARRAY') {
               @values = @{$save{$name}};
           } elsif (ref($save{$name}) eq 'HASH') {
               foreach my $key (%{$save{$name}}) {
                   push(@values,&escape($key).'='.&escape($save{$name}{$key}));
               }
           } else {
               @values = $save{$name};
           }
           # We handle array and hash references, but not recursively.
         my $store = join(',', map { &escape($_); } @values );          my $store = join(',', map { &escape($_); } @values );
         $persistent_db{$name} = $store;          $persistent_db{$name} = $store;
     }      }
Line 1392  sub parse_advanced_search { Line 1323  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') {
  $env{'form.'.$field}=~s/[^\w\/\s\(\)\=\-\"\']//g;   $env{'form.'.$field}=~s/[^\w\/\s\(\)\=\-\"\'.\*]//g;
     }      }
     foreach ('mode','form','element') {      foreach ('mode','form','element') {
  # is this required?  Hmmm.   # is this required?  Hmmm.
Line 1438  sub parse_advanced_search { Line 1369  sub parse_advanced_search {
     }      }
     if (! $fillflag) {      if (! $fillflag) {
  &output_blank_field_error($r,$closebutton,   &output_blank_field_error($r,$closebutton,
                                   'phase=disp_adv',$hidden_fields);                                    'phase=disp_adv&amp;area='.$env{'form.area'}.
  return ;                                    '&amp;catalogmode='.$env{'form.catalogmode'},
                                     $hidden_fields);
    return;
     }      }
     # Turn the form input into a SQL-based query      # Turn the form input into a SQL-based query
     my $query='';      my $query='';
Line 1452  sub parse_advanced_search { Line 1385  sub parse_advanced_search {
             &process_phrase_input($env{'form.'.$field},              &process_phrase_input($env{'form.'.$field},
                                   $env{'form.'.$field.'_related'},$field);                                    $env{'form.'.$field.'_related'},$field);
         if (defined($error)) {          if (defined($error)) {
             &output_unparsed_phrase_error($r,$closebutton,'phase=disp_adv',              &output_unparsed_phrase_error($r,$closebutton,
                                            'phase=disp_adv&amp;area='.$env{'form.area'}.
                                            '&amp;catalogmode='.$env{'form.catalogmode'}.
                                          $hidden_fields,$field);                                           $hidden_fields,$field);
             return;              return;
         } else {          } else {
Line 1630  sub parse_advanced_search { Line 1565  sub parse_advanced_search {
     ##      ##
     ## Deal with restrictions to given domains      ## Deal with restrictions to given domains
     ##       ## 
     my ($libraries_to_query,$pretty_domains_string) = &parse_domain_restrictions();      my ($libraries_to_query,$pretty_domains_string,$domains_to_query) = 
           &parse_domain_restrictions();
     if ($pretty_domains_string) {      if ($pretty_domains_string) {
        $pretty_search_string .= $pretty_domains_string."<br />\n";         $pretty_search_string .= $pretty_domains_string."<br />\n";
     }      }
     #      #
     if (@queries) {      if (@queries) {
         if ($env{'form.area'} eq 'portfolio') {          if ($env{'form.area'} eq 'portfolio') {
             $query ="SELECT pm.*,pa.keynum,pa.scope FROM portfolio_metadata pm, portfolio_access pa, portfolio_addedfields pf WHERE (pm.url = pa.url AND pf.url = pm.url AND (pa.start < NOW() AND (pa.end IS NULL OR pa.end > NOW())) AND (".join(') AND (',@queries).'))';              $query ="SELECT pm.*,pa.keynum,pa.scope FROM portfolio_metadata pm, portfolio_access pa, portfolio_addedfields pf WHERE (pm.url = pa.url AND pf.url = pm.url AND (pa.start < UTC_TIMESTAMP() AND (pa.end IS NULL OR pa.end > UTC_TIMESTAMP())) AND (".join(') AND (',@queries).'))';
         } else {          } else {
     $query="SELECT * FROM metadata WHERE (".join(") AND (",@queries).')';      $query="SELECT * FROM metadata WHERE (".join(") AND (",@queries).')';
         }          }
Line 1646  sub parse_advanced_search { Line 1582  sub parse_advanced_search {
     }      }
     #&Apache::lonnet::logthis('advanced query = '.$/.$query);      #&Apache::lonnet::logthis('advanced query = '.$/.$query);
     return ($query,$customquery,$customshow,$libraries_to_query,      return ($query,$customquery,$customshow,$libraries_to_query,
             $pretty_search_string);              $pretty_search_string,$domains_to_query);
 }  }
   
 sub parse_domain_restrictions {  sub parse_domain_restrictions {
     my $libraries_to_query = undef;      my $libraries_to_query = undef;
       my $domains_to_query = undef;
     # $env{'form.domains'} can be either a scalar or an array reference.      # $env{'form.domains'} can be either a scalar or an array reference.
     # We need an array.      # We need an array.
     if (! exists($env{'form.domains'}) || $env{'form.domains'} eq '') {      if (! exists($env{'form.domains'}) || $env{'form.domains'} eq '') {
Line 1674  sub parse_domain_restrictions { Line 1611  sub parse_domain_restrictions {
         foreach (sort @allowed_domains) {          foreach (sort @allowed_domains) {
             $pretty_domains_string .= "<b>".$_."</b> ";              $pretty_domains_string .= "<b>".$_."</b> ";
         }          }
  my %servers = &Apache::lonnet::get_servers(\@allowed_domains,   my %library_servers = &Apache::lonnet::get_unique_servers(\@allowed_domains,
    'library');                    'library');
           my (%older_library_servers,%okdoms,%domains_for_id);
           map { $okdoms{$_} = 1; } @allowed_domains;
           foreach my $key (keys(%library_servers)) {
               if (&Apache::lonnet::get_server_loncaparev('',$key) =~ /^\'?(\d+)\.(\d+)/) {
                   my $major = $1;
                   my $minor = $2;
                   if (($major < 2) || (($major == 2) && ($minor < 11))) {
                       map { $older_library_servers{$_} = 1; }
                           &Apache::lonnet::machine_ids($library_servers{$key});
                   } else {
                       my %possdoms;
                       map { $possdoms{$_}=1 if ($okdoms{$_}); }
                           &Apache::lonnet::machine_domains($library_servers{$key});
                       $domains_for_id{$key} = join(',',sort(keys(%possdoms)));
                   }
               }
           }
           my %servers = (%library_servers,%older_library_servers);
  $libraries_to_query = [keys(%servers)];   $libraries_to_query = [keys(%servers)];
           $domains_to_query = \%domains_for_id;
     }      }
     return ($libraries_to_query,      return ($libraries_to_query,
             $pretty_domains_string);              $pretty_domains_string,
               $domains_to_query);
 }  }
   
 ######################################################################  ######################################################################
Line 1700  sub parse_basic_search { Line 1657  sub parse_basic_search {
     #      #
     # 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;
     }      }
     foreach ('mode','form','element') {      foreach ('mode','form','element') {
  # is this required?  Hmmm.   # is this required?  Hmmm.
Line 1708  sub parse_basic_search { Line 1665  sub parse_basic_search {
  $env{"form.$_"}=&unescape($env{"form.$_"});   $env{"form.$_"}=&unescape($env{"form.$_"});
  $env{"form.$_"}=~s/[^\w\/\s\(\)\=\-\"\']//g;   $env{"form.$_"}=~s/[^\w\/\s\(\)\=\-\"\']//g;
     }      }
     my ($libraries_to_query,$pretty_domains_string) = &parse_domain_restrictions();      my ($libraries_to_query,$pretty_domains_string,$domains_to_query) = 
           &parse_domain_restrictions();
     #      #
     # Check to see if enough of a query is filled in      # Check to see if enough of a query is filled in
     my $search_string = $env{'form.basicexp'};      my $search_string = $env{'form.basicexp'};
     if (! &filled($search_string)) {      if (! &filled($search_string)) {
  &output_blank_field_error($r,$closebutton,'phase=disp_basic');   &output_blank_field_error($r,$closebutton,'phase=disp_basic'.
                                     '&amp;area='.$env{'form.area'}.
                                     '&amp;catalogmode='.$env{'form.catalogmode'});
  return OK;   return OK;
     }      }
     my $pretty_search_string=$search_string;      my $pretty_search_string=$search_string;
Line 1729  sub parse_basic_search { Line 1689  sub parse_basic_search {
                                                     $env{'form.related'},                                                      $env{'form.related'},
                                                     $searchfield);                                                      $searchfield);
     if ($error) {      if ($error) {
         &output_unparsed_phrase_error($r,$closebutton,'phase=disp_basic',          &output_unparsed_phrase_error($r,$closebutton,'phase=disp_basic'.
                                         '&amp;area='.$env{'form.area'}.
                                         '&amp;catalogmode='.$env{'form.catalogmode'},
                                       '','basicexp');                                        '','basicexp');
         return;          return;
     }      }
Line 1739  sub parse_basic_search { Line 1701  sub parse_basic_search {
     #}      #}
     my $final_query;      my $final_query;
     if ($env{'form.area'} eq 'portfolio') {      if ($env{'form.area'} eq 'portfolio') {
         $final_query = 'SELECT pm.*,pa.keynum,pa.scope FROM portfolio_metadata pm, portfolio_access pa  WHERE (pm.url = pa.url AND (pa.start < NOW() AND (pa.end IS NULL OR pa.end > NOW())) AND '.join(" AND ",@Queries).')';          $final_query = 'SELECT pm.*,pa.keynum,pa.scope FROM portfolio_metadata pm, portfolio_access pa  WHERE (pm.url = pa.url AND (pa.start < UTC_TIMESTAMP() AND (pa.end IS NULL OR pa.end > UTC_TIMESTAMP())) AND '.join(" AND ",@Queries).')';
     } else {      } else {
         $final_query = 'SELECT * FROM metadata WHERE '.join(" AND ",@Queries);          $final_query = 'SELECT * FROM metadata WHERE '.join(" AND ",@Queries);
     }      }
Line 1754  sub parse_basic_search { Line 1716  sub parse_basic_search {
     $pretty_search_string =~ s:^<br /> and ::;      $pretty_search_string =~ s:^<br /> and ::;
     &Apache::lonnet::logthis('simple search final query = '.$/.$final_query);      &Apache::lonnet::logthis('simple search final query = '.$/.$final_query);
     return ($final_query,$pretty_search_string,      return ($final_query,$pretty_search_string,
             $libraries_to_query);              $libraries_to_query,$domains_to_query);
 }  }
   
   
Line 1855  sub process_phrase_input { Line 1817  sub process_phrase_input {
             $item[1];              $item[1];
         }          }
     term:      term:
         /[\w\Q:!@#$%^&*()+_=|{}<>,.;\\\/?\E]+/ {          /[\w\Q:!@#$%^&*()+_=|{}<>,.;\\\/?\E\-]+/ {
             $item[1];              $item[1];
         }          }
 ENDGRAMMAR  ENDGRAMMAR
Line 2026  sub build_date_queries { Line 1988  sub build_date_queries {
     if ((defined($cafter)  && ! defined($cbefore)) ||      if ((defined($cafter)  && ! defined($cbefore)) ||
         (defined($cbefore) && ! defined($cafter))) {          (defined($cbefore) && ! defined($cafter))) {
         # This is bad, so let them know          # This is bad, so let them know
         $error = &mt('Incorrect entry for the creation date.  '.          $error = &mt('Incorrect entry for the creation date. '.
                     'You must specify both the beginning and ending dates.');                      'You must specify both the beginning and ending dates.');
     }      }
     if (! defined($error) &&       if (! defined($error) && 
         ((defined($mafter)  && ! defined($mbefore)) ||          ((defined($mafter)  && ! defined($mbefore)) ||
         (defined($mbefore) && ! defined($mafter)))) {          (defined($mbefore) && ! defined($mafter)))) {
         # This is also bad, so let them know          # This is also bad, so let them know
         $error = &mt('Incorrect entry for the last revision date.  '.          $error = &mt('Incorrect entry for the last revision date. '.
                      'You must specify both the beginning and ending dates.');                       'You must specify both the beginning and ending dates.');
     }      }
     if (! defined($error)) {      if (! defined($error)) {
Line 2045  sub build_date_queries { Line 2007  sub build_date_queries {
             my (undef,undef,undef,$cbday,$cbmon,$cbyear) = localtime($cbefore);              my (undef,undef,undef,$cbday,$cbmon,$cbyear) = localtime($cbefore);
             # Correct for year being relative to 1900              # Correct for year being relative to 1900
             $cayear+=1900; $cbyear+=1900;              $cayear+=1900; $cbyear+=1900;
               # Correct month; localtime gives month 0..11 but MySQL expects 1..12
               $camon++; $cbmon++;
             my $cquery=              my $cquery=
                 '(creationdate BETWEEN '.                  '(creationdate BETWEEN '.
                 "'".$cayear.'-'.$camon.'-'.$caday."'".                  "'".$cayear.'-'.$camon.'-'.$caday."'".
Line 2063  sub build_date_queries { Line 2027  sub build_date_queries {
             my (undef,undef,undef,$mbday,$mbmon,$mbyear) = localtime($mbefore);              my (undef,undef,undef,$mbday,$mbmon,$mbyear) = localtime($mbefore);
             # Correct for year being relative to 1900              # Correct for year being relative to 1900
             $mayear+=1900; $mbyear+=1900;              $mayear+=1900; $mbyear+=1900;
               # Correct month; localtime gives month 0..11 but MySQL expects 1..12
               $mamon++; $mbmon++;
             my $mquery=              my $mquery=
                 '(lastrevisiondate BETWEEN '.                  '(lastrevisiondate BETWEEN '.
                 "'".$mayear.'-'.$mamon.'-'.$maday."'".                  "'".$mayear.'-'.$mamon.'-'.$maday."'".
Line 2105  sub copyright_check { Line 2071  sub copyright_check {
     my (undef,undef,$resdom,$resname) = split('/',      my (undef,undef,$resdom,$resname) = split('/',
                                               $Metadata->{'url'});                                                $Metadata->{'url'});
     # Check for priv      # Check for priv
     if (($Metadata->{'copyright'} eq 'priv') &&       if ($Metadata->{'copyright'} eq 'priv') {
         (($env{'user.name'} ne $resname) &&          unless (($env{'user.name'} eq $resname) &&
          ($env{'user.domain'} ne $resdom))) {                  ($env{'user.domain'} eq $resdom)) {
         return 0;              return 0;
           }
     }      }
     # Check for domain      # Check for domain
     if (($Metadata->{'copyright'} eq 'domain') &&      if (($Metadata->{'copyright'} eq 'domain') &&
         ($env{'user.domain'} ne $resdom)) {          ($env{'user.domain'} ne $resdom)) {
         return 0;          return 0;
     }      }
       # Check for custom rights
       if ($Metadata->{'copyright'} eq 'custom') {
          return &Apache::lonnet::customaccess('bre',$Metadata->{'url'});
       }
     return 1;      return 1;
 }  }
   
Line 2142  sub ensure_db_and_table { Line 2113  sub ensure_db_and_table {
     ## Sanity check the table id.      ## Sanity check the table id.
     ##      ##
     if (! defined($table) || $table eq '' || $table =~ /\D/ ) {      if (! defined($table) || $table eq '' || $table =~ /\D/ ) {
         $r->print("Unable to retrieve search results.  ".          $r->print(&Apache::loncommon::start_page('Error')
                   "Unable to determine the table results were stored in.  ".                   .'<p class="LC_error">'
   &Apache::loncommon::end_page());                   .&mt('Unable to retrieve search results. '
                        .'Unable to determine the table results were saved in.')
                    .'</p>'
                    . '<p>'.&mt('Internal info:').'</p>'
                    .'<pre>'.$table.'</pre>'
                    .&Apache::loncommon::end_page()
           );
         return undef;          return undef;
     }      }
     ##      ##
Line 2152  sub ensure_db_and_table { Line 2129  sub ensure_db_and_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)) {
         $r->print("Unable to connect to the MySQL database where your results".          $r->print(
                   " are stored.".              '<p class="LC_error">'
   &Apache::loncommon::end_page());             .&mt('Unable to connect to the MySQL database where your results are saved.')
              .'</p>'
              .&Apache::loncommon::end_page()
           );
         &Apache::lonnet::logthis("lonsearchcat: unable to get lonmysql to".          &Apache::lonnet::logthis("lonsearchcat: unable to get lonmysql to".
                                  " connect to database.");                                   " connect to database.");
         &Apache::lonnet::logthis(&Apache::lonmysql::get_error());          &Apache::lonnet::logthis(&Apache::lonmysql::get_error());
Line 2162  sub ensure_db_and_table { Line 2142  sub ensure_db_and_table {
     }      }
     my $table_check = &Apache::lonmysql::check_table($table);      my $table_check = &Apache::lonmysql::check_table($table);
     if (! defined($table_check)) {      if (! defined($table_check)) {
         $r->print("A MySQL error has occurred.</form>".          $r->print(
   &Apache::loncommon::end_page());              '<p class="LC_error">'
              .&mt('A MySQL error has occurred.')
              .'</p></form>'
              .&Apache::loncommon::end_page());
         &Apache::lonnet::logthis("lonmysql was unable to determine the status".          &Apache::lonnet::logthis("lonmysql was unable to determine the status".
                                  " of table ".$table);                                   " of table ".$table);
         return undef;          return undef;
     } elsif (! $table_check) {      } elsif (! $table_check) {
         $r->print("The table of results could not be found.");          $r->print(
               '<p class="LC_error">'
              .&mt('The table of results could not be found.')
              .'</p>'
           );
         &Apache::lonnet::logthis("The user requested a table, ".$table.          &Apache::lonnet::logthis("The user requested a table, ".$table.
                                  ", that could not be found.");                                   ", that could not be found.");
         return undef;          return undef;
Line 2191  a link to change the search query. Line 2178  a link to change the search query.
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
 sub print_sort_form {  sub print_sort_form {
     my ($r,$pretty_query_string) = @_;      my ($r,$pretty_query_string,$target) = @_;
   
     ##      ##
     my %SortableFields=&Apache::lonlocal::texthash(       my %SortableFields=&Apache::lonlocal::texthash( 
Line 2224  sub print_sort_form { Line 2211  sub print_sort_form {
         &Apache::lonnet::logthis(&Apache::lonmysql::get_error());          &Apache::lonnet::logthis(&Apache::lonmysql::get_error());
         return;          return;
     }      }
     my $js =<<END;      my $args;
 <script type="text/javascript">      if ($target eq '_parent') {
     function change_sort() {          $args = {'links_target' => $target};
         var newloc = "/adm/searchcat?phase=results";  
         newloc += "&persistent_db_id=$env{'form.persistent_db_id'}";  
         newloc += "&sortby=";  
         newloc += document.forms.statusform.elements.sortby.value;  
         parent.resultsframe.location= newloc;  
     }      }
 </script>      my $start_page = &Apache::loncommon::start_page('Results',undef,$args);
 END  
   
     my $start_page = &Apache::loncommon::start_page('Results',$js,  
     {'no_title' => 1});  
     my $breadcrumbs=      my $breadcrumbs=
         &Apache::lonhtmlcommon::breadcrumbs('Searching','Searching',          &Apache::lonhtmlcommon::breadcrumbs('Searching','Searching',
     $env{'form.catalogmode'} ne 'import');      $env{'form.catalogmode'} ne 'import',
                                               '','','','','','',$target);
     my $result = <<END;      my $result = <<END;
 $start_page  $start_page
 $breadcrumbs  $breadcrumbs
 <form name="statusform" action="" method="post" target="_top">  <div class="LC_landmark" role="main">
   <form name="statusform" action="" method="post" target="$target">
 <input type="hidden" name="catalogmode" value="import" />  <input type="hidden" name="catalogmode" value="import" />
 <input type="hidden" name="acts" value="" />  <input type="hidden" name="acts" value="" />
 END  END
Line 2262  END Line 2241  END
 #    }  #    }
 #    $result.="</select>\n";  #    $result.="</select>\n";
     my $revise = &revise_button();      my $revise = &revise_button();
     $result.=<<END;      $result.='<p>'
 <p>              .&mt('Total of [quant,_1,match,matches] to your query.',$total_results)
 There are $total_results matches to your query. $revise              .' '.$revise.'</p>'
 </p><p>              .'<p>'.&mt('Search: ').$pretty_query_string
 Search: $pretty_query_string              .'</p></form>';
 </p>      $r->print($result.'</div>'.&Apache::loncommon::end_page());
 </form>  
 END  
     $r->print($result.&Apache::loncommon::end_page());  
     return;      return;
 }  }
   
Line 2379  Returns: Nothing. Line 2355  Returns: Nothing.
 sub update_count_status {  sub update_count_status {
     my ($r,$text) = @_;      my ($r,$text) = @_;
     $text =~ s/\'/\\\'/g;      $text =~ s/\'/\\\'/g;
     $r->print      $r->print(<<SCRIPT);
         ("<script>document.statusform.count.value = ' $text'</script>\n");  <script type="text/javascript">
   // <![CDATA[
   document.statusform.count.value = ' $text'
   // ]]>
   </script>
   SCRIPT
   
     $r->rflush();      $r->rflush();
 }  }
   
 sub update_status {  sub update_status {
     my ($r,$text) = @_;      my ($r,$text) = @_;
     $text =~ s/\'/\\\'/g;      $text =~ s/\'/\\\'/g;
     $r->print      $r->print(<<SCRIPT);
         ("<script>document.statusform.status.value = ' $text'</script>\n");  <script type="text/javascript">
   // <![CDATA[
   document.statusform.status.value = ' $text'
   // ]]>
   </script>
   SCRIPT
   
       $r->rflush();
   }
   
   sub reload_result_frame {
       my ($r) = @_;
       my $newloc = '/adm/searchcat?phase=results&persistent_db_id='.
           $env{'form.persistent_db_id'}.'&area='.$env{'form.area'}.
           '&catalogmode='.$env{'form.catalogmode'};
       $r->print(<<SCRIPT);
   <script type="text/javascript">
       parent.update_results("$newloc");
   </script>
   SCRIPT
   
     $r->rflush();      $r->rflush();
 }  }
   
 {  {
     my $max_time  = 300;  # seconds for the search to complete      my $max_time  = 60;  # seconds for the search to complete
     my $start_time = 0;      my $start_time = 0;
     my $last_time = 0;      my $last_time = 0;
   
Line 2415  sub update_seconds { Line 2417  sub update_seconds {
     my ($r) = @_;      my ($r) = @_;
     my $time = &time_left();      my $time = &time_left();
     if (($last_time-$time) > 0) {      if (($last_time-$time) > 0) {
         $r->print("<script>".          $r->print(<<SCRIPT);
                   "document.statusform.seconds.value = '$time'".  <script type="text/javascript">
                   "</script>\n");  // <![CDATA[
   document.statusform.seconds.value = '$time'
   // ]]>
   </script>
   SCRIPT
   
         $r->rflush();          $r->rflush();
     }      }
     $last_time = $time;      $last_time = $time;
Line 2441  Returns: html string for a 'revise searc Line 2448  Returns: html string for a 'revise searc
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
 sub revise_button {  sub revise_button {
       my $revisetext = &mt('Revise search');
     my $revise_phase = 'disp_basic';      my $revise_phase = 'disp_basic';
     $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'.              '&amp;cleargroupsort=1'.
             '&phase='.$revise_phase;              '&amp;phase='.$revise_phase.
     my $result = qq{<input type="button" value="Revise search" name="revise"} .              '&amp;area='.$env{'form.area'}.
         qq{ onClick="parent.location='$newloc';" /> };              '&amp;catalogmode='.$env{'form.catalogmode'};
       my $result = qq{<input type="button" value="$revisetext" name="revise"} .
           qq{ onclick="parent.location='$newloc';" /> };
     return $result;      return $result;
 }  }
   
Line 2468  results into MySQL. Line 2478  results into MySQL.
 ######################################################################  ######################################################################
 sub run_search {  sub run_search {
     my ($r,$query,$customquery,$customshow,$serverlist,      my ($r,$query,$customquery,$customshow,$serverlist,
         $pretty_string,$area) = @_;          $pretty_string,$area,$domainsref,$target) = @_;
     my $tabletype = 'metadata';      my $tabletype = 'metadata';
     if ($area eq 'portfolio') {      if ($area eq 'portfolio') {
         $tabletype = 'portfolio_search';          $tabletype = 'portfolio_search';
Line 2477  sub run_search { Line 2487  sub run_search {
     #      #
     # Print run_search header      # Print run_search header
     #      #
     my $start_page = &Apache::loncommon::start_page('Search Status',undef,      my $args;
     {'no_title' => 1});      if ($target eq '_parent') {
           $args = {'links_target' => $target};
       }
       my $start_page = &Apache::loncommon::start_page('Search Status',undef,$args);
     my $breadcrumbs =      my $breadcrumbs =
  &Apache::lonhtmlcommon::breadcrumbs('Searching','Searching',   &Apache::lonhtmlcommon::breadcrumbs('Searching','Searching',
     $env{'form.catalogmode'} ne 'import');      $env{'form.catalogmode'} ne 'import',
                                               '','','','','','',$target);
     $r->print(<<END);      $r->print(<<END);
 $start_page  $start_page
 $breadcrumbs  $breadcrumbs
 <form name="statusform" action="" method="post">  <div class="LC_landmark" role="main">
 <input type="hidden" name="acts" value="" />  
 END  END
     # Remove leading and trailing <br />      # Remove leading and trailing <br />
     $pretty_string =~ s:^\s*<br />::i;      $pretty_string =~ s:^\s*<br />::i;
Line 2497  END Line 2510  END
         pop(@Lines);          pop(@Lines);
     }      }
     if (@Lines > 2) {      if (@Lines > 2) {
         $pretty_string = join '<br />',(@Lines[0..2],'....<br />');          $pretty_string = join '<br />',(@Lines[0..2],'...<br />');
     }      }
     $r->print(&mt("Search: [_1]",$pretty_string));      $r->print(&mt("Search: [_1]",$pretty_string));
     $r->rflush();      $r->rflush();
     #      #
     # Determine the servers we need to contact.      # Determine the servers we need to contact.
     my @Servers_to_contact;      my (@Servers_to_contact,%domains_by_server);
     if (defined($serverlist)) {      if (defined($serverlist)) {
         if (ref($serverlist) eq 'ARRAY') {          if (ref($serverlist) eq 'ARRAY') {
             @Servers_to_contact = @$serverlist;              @Servers_to_contact = @$serverlist;
         } else {          } else {
             @Servers_to_contact = ($serverlist);              @Servers_to_contact = ($serverlist);
         }          }
           if (ref($domainsref) eq 'HASH') {
               foreach my $server (@Servers_to_contact) {
                   $domains_by_server{$server} = $domainsref->{$server};
               }
           }
     } else {      } else {
  my %all_library_servers = &Apache::lonnet::all_library();   my %library_servers = &Apache::lonnet::unique_library();
           my (%all_library_servers, %older_library_servers);
           foreach my $key (keys(%library_servers)) {
               if (&Apache::lonnet::get_server_loncaparev('',$key) =~ /^\'?(\d+)\.(\d+)/) {
                   my $major = $1;
                   my $minor = $2;
                   if (($major < 2) || (($major == 2) && ($minor < 11))) {
                       map { $older_library_servers{$_} = 1; }
                           &Apache::lonnet::machine_ids($library_servers{$key});
                   }
               }
           }
           %all_library_servers = (%library_servers,%older_library_servers);
         @Servers_to_contact = sort(keys(%all_library_servers));          @Servers_to_contact = sort(keys(%all_library_servers));
           foreach my $server (@Servers_to_contact) {
               $domains_by_server{$server} =
                   join(',',sort(&Apache::lonnet::machine_domains($all_library_servers{$server})));
           }
     }      }
     my %Server_status;      my %Server_status;
     #      #
     # Check on the mysql table we will use to store results.      # Check on the mysql table we will use to store results.
     my $table =$env{'form.table'};      my $table =$env{'form.table'};
     if (! defined($table) || $table eq '' || $table =~ /\D/ ) {      if (! defined($table) || $table eq '' || $table =~ /\D/ ) {
         $r->print("Unable to determine table id to store search results in.".          $r->print("Unable to determine table id to save search results in.".
                   "The search has been aborted.".                    "The search has been aborted.".
   &Apache::loncommon::end_page());    &Apache::loncommon::end_page());
         return;          return;
Line 2548  END Line 2582  END
     ##      ##
     ## Prepare for the big loop.      ## Prepare for the big loop.
     my $hitcountsum;      my $hitcountsum;
       my $oldhitcountsum;
       my $displaycount;
     my %matches;      my %matches;
     my $server;       my $server; 
     my $status;      my $status;
     my $revise = &revise_button();      my $revise = &revise_button();
     $r->print(<<END);      $r->print('<form name="statusform" action="" method="post">'."\n".
 <table>                '<input type="hidden" name="acts" value="" />'."\n".
 <tr><th>Status</th><th>Total Matches</th><th>Time Remaining</th><th></th></tr>                '<table border="0"><tr><td>'."\n".
 <tr>                &Apache::loncommon::start_data_table());
 <td><input type="text" name="status"  value="" size="50" /></td>      $r->print(&Apache::loncommon::start_data_table_header_row()
 <td><input type="text" name="count"   value="" size="10" /></td>               .'<th>'.&mt('Status').'</th>'
 <td><input type="text" name="seconds" value="" size="8" /></td>               .'<th>'.&mt('Total Matches').'</th>'
 <td>$revise</td>               .'<th>'.&mt('Time Remaining').'</th>'
 </tr>               .&Apache::loncommon::end_data_table_header_row()
 </table>               .&Apache::loncommon::start_data_table_row()
 </form>               .'<td><input type="text" name="status"  value="" size="50" readonly="readonly" /></td>'
 END               .'<td><input type="text" name="count"   value="" size="10" readonly="readonly" /></td>'
                .'<td><input type="text" name="seconds" value="" size="8" readonly="readonly" /></td>'
                .&Apache::loncommon::end_data_table_row()
                .&Apache::loncommon::end_data_table()
                .'</td><td>&nbsp;</td><td>'.$revise.'</td></tr></table></form>');
     $r->rflush();      $r->rflush();
     &reset_timing();      &reset_timing();
     &update_seconds($r);      &update_seconds($r);
Line 2578  END Line 2618  END
             my $server = shift(@Servers_to_contact);              my $server = shift(@Servers_to_contact);
             &update_status($r,&mt('contacting [_1]',$server));              &update_status($r,&mt('contacting [_1]',$server));
             my $reply=&Apache::lonnet::metadata_query($query,$customquery,              my $reply=&Apache::lonnet::metadata_query($query,$customquery,
                                                       $customshow,[$server]);                                                        $customshow,[$server],\%domains_by_server);
             ($server) = keys(%$reply);              ($server) = keys(%$reply);
             $Server_status{$server} = $reply->{$server};              $Server_status{$server} = $reply->{$server};
         } else {          } else {
Line 2590  END Line 2630  END
                 &update_status($r,                  &update_status($r,
                        &mt('waiting on [_1]',join(' ',keys(%Server_status))));                         &mt('waiting on [_1]',join(' ',keys(%Server_status))));
             }              }
             sleep(1)              sleep(0.1);
         }          }
         #          #
         # Loop through the servers we have contacted but do not          # Loop through the servers we have contacted but do not
Line 2604  END Line 2644  END
                 next;                  next;
             }              }
             $status=~s|/||g;              $status=~s|/||g;
            my $datafile=$r->dir_config('lonDaemons').'/tmp/'.$status;  
   
   
              my $datafile=LONCAPA::tempdir().$status;
             if (-e $datafile && ! -e "$datafile.end") {              if (-e $datafile && ! -e "$datafile.end") {
                 &update_status($r,&mt('Receiving results from [_1]',$server));                  &update_status($r,&mt('Receiving results from [_1]',$server));
                 next;                  next;
Line 2635  END Line 2678  END
                     my %Fields = &parse_raw_result($result,$server,$tabletype);                      my %Fields = &parse_raw_result($result,$server,$tabletype);
                     $Fields{'hostname'} = $server;                      $Fields{'hostname'} = $server;
                     #                      #
                     # Skip if external and we did not want that  
                     next if ((! $env{'form.inclext'}) && ($Fields{'url'}=~/^\/ext\//));  
                     # Skip based on copyright                      # Skip based on copyright
                     next if (! &copyright_check(\%Fields));                      next if (! &copyright_check(\%Fields));
   
                     if ($area eq 'portfolio') {                      if ($area eq 'portfolio') {
                         next if (defined($matches{$Fields{'url'}}));                          next if (defined($matches{$Fields{'url'}}));
                         # Skip if inaccessible                          # Skip unless access control set to public or passphrase-protected
                         next if (!&Apache::lonnet::portfolio_access($Fields{'url'}));                          next unless (($Fields{'scope'} eq 'public') || ($Fields{'scope'} eq 'guest'));
                         $matches{$Fields{'url'}} = 1;                           $matches{$Fields{'url'}} = 1; 
                     }                      }
                     #                      #
Line 2665  END Line 2706  END
                 delete($Server_status{$server});                  delete($Server_status{$server});
             }              }
             last if ($connection->aborted());              last if ($connection->aborted());
             &update_count_status($r,$hitcountsum);              if ($oldhitcountsum < $hitcountsum) {
                   &update_count_status($r,$hitcountsum);
                   if (($hitcountsum <= $env{'form.show'}) ||
                       (!$displaycount && $hitcountsum)) {
                       reload_result_frame($r);
                       $displaycount = $hitcountsum;
                   }
                   $oldhitcountsum = $hitcountsum;
               }
         }          }
         last if ($connection->aborted());          last if ($connection->aborted());
         &update_seconds($r);          &update_seconds($r);
     }      }
     &update_status($r,&mt('Search Complete [_1]',$server));      &update_status($r,&mt('Search Complete on Server [_1]',$server));
     &update_seconds($r);      &update_seconds($r);
     #      #
     &Apache::lonmysql::disconnect_from_db(); # This is unneccessary      &Apache::lonmysql::disconnect_from_db(); # This is unneccessary
Line 2678  END Line 2727  END
     # 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, so let the client know the top frame needs to be      # results to get, so let the client know the top frame needs to be
     # loaded from /adm/searchcat      # loaded from /adm/searchcat
     $r->print(&Apache::loncommon::end_page());      $r->print('</div>'.&Apache::loncommon::end_page());
 #    if ($env{'form.catalogmode'} ne 'import') {  #    if ($env{'form.catalogmode'} ne 'import') {
         $r->print("<script>".           $r->print(<<SCRIPT);
                       "window.location='/adm/searchcat?".  <script>
                       "phase=sort&".  window.location='/adm/searchcat?phase=sort&area=$env{"form.area"}&catalogmode=$env{"form.catalogmode"}&persistent_db_id=$env{'form.persistent_db_id'}';
                       "persistent_db_id=$env{'form.persistent_db_id'}';".  </script>
                   "</script>");  SCRIPT
 #    }  #    }
     return;      return;
 }  }
Line 2707  sub prev_next_buttons { Line 2756  sub prev_next_buttons {
     return '' if ($show eq 'all'); # No links if you get them all at once.      return '' if ($show eq 'all'); # No links if you get them all at once.
     #      #
     # Create buttons      # Create buttons
     my $buttons = '<input type="submit" name="prev" value="'.&mt('Prev').'" ';      return '<p class="LC_nobreak">'
     $buttons .= '/>';            .'<input type="submit" name="prev" value="&lt;"'
     $buttons .= '&nbsp;'x3;            .' title="'.&mt('Previous').'" />'
     $buttons .= '<input type="submit" name="reload" '.            .' '
         'value="'.&mt('Reload').'" />';            .'<input type="submit" name="reload" value="'.&mt('Reload').'" />'
     $buttons .= '&nbsp;'x3;            .' '
     $buttons .= '<input type="submit" name="next" value="'.&mt('Next').'" ';            .'<input type="submit" name="next" value="&gt;"'
     $buttons .= '/>';            .' title="'.&mt('Next').'" />'
     return $buttons;            .'</p>';
 }  }
   
 ######################################################################  ######################################################################
Line 2740  sub display_results { Line 2789  sub display_results {
     ##      ##
     my $viewfunction = $Views{$env{'form.viewselect'}};      my $viewfunction = $Views{$env{'form.viewselect'}};
     if (!defined($viewfunction)) {      if (!defined($viewfunction)) {
         $r->print("Internal Error - Bad view selected.\n");          $r->print('<p class="LC_error">'
                    .&mt('Internal Error - Bad view selected.')
                    .'</p>'."\n"
                    .'</form></div>'.&Apache::loncommon::end_page());
         $r->rflush();          $r->rflush();
         return;          return;
     }      }
Line 2751  sub display_results { Line 2803  sub display_results {
     ##      ##
     ## Get the catalog controls setup      ## Get the catalog controls setup
     ##      ##
     my $action = "/adm/searchcat?phase=results";      my $action = "/adm/searchcat?phase=results&amp;area='.$env{'form.area'}.
                    '&amp;catalogmode='.$env{'form.catalogmode'};
     ##      ##
     ## Deal with import by opening the import db file.      ## Deal with import by opening the import db file.
     if ($env{'form.catalogmode'} eq 'import') {      if ($env{'form.catalogmode'} eq 'import') {
         if (! tie(%groupsearch_db,'GDBM_File',$diropendb,          if (! tie(%groupsearch_db,'GDBM_File',$diropendb,
                   &GDBM_WRCREAT(),0640)) {                    &GDBM_WRCREAT(),0640)) {
             $r->print('Unable to store import results.</form>'.              # NOTE: this can happen when a previous request to searchcat?phase=results gets interrupted
               # (%groupsearch_db is not untied)
               $r->print('<p class="LC_error">'.
                 &mt('Unable to save import results.').
                 '</p>'.
                 '</form></div>'.
       &Apache::loncommon::end_page());        &Apache::loncommon::end_page());
             $r->rflush();              $r->rflush();
             return;              return;
         }           } 
           # untie %groupsearch_db if the connection gets aborted before the end
           $r->register_cleanup(sub {
               untie %groupsearch_db if (tied(%groupsearch_db));
           });
     }      }
     ##      ##
     ## Prepare the table for querying      ## Prepare the table for querying
Line 2771  sub display_results { Line 2833  sub display_results {
     ## Get the number of results       ## Get the number of results 
     my $total_results = &Apache::lonmysql::number_of_rows($table);      my $total_results = &Apache::lonmysql::number_of_rows($table);
     if (! defined($total_results)) {      if (! defined($total_results)) {
         $r->print("A MySQL error has occurred.</form>".          $r->print('<p class="LC_error">'.
             &mt('A MySQL error has occurred.').
             '</p>'.
             '</form></div>'.
   &Apache::loncommon::end_page());    &Apache::loncommon::end_page());
         &Apache::lonnet::logthis("lonmysql was unable to determine the number".          &Apache::lonnet::logthis("lonmysql was unable to determine the number".
                                  " of rows in table ".$table);                                   " of rows in table ".$table);
Line 2876  sub display_results { Line 2941  sub display_results {
     $env{'form.sortorder'}='asc';      $env{'form.sortorder'}='asc';
  }   }
     }      }
     my $sortform = &mt('Sort by [_1] [_2]',      my $sortform = '<span class="LC_nobreak"><span id="LC_sortby">'
                        &Apache::loncommon::select_form($env{'form.sortfield'},                    .&mt('Sort by:').'</span> '
                                                       'sortfield',                    .&Apache::loncommon::select_form($env{'form.sortfield'},
                                                       %sort_fields),                                                     'sortfield',
                        &Apache::loncommon::select_form($env{'form.sortorder'},                                                     \%sort_fields,'','','',
                                                       'sortorder',                                                     'LC_sortby')
                                                       (asc =>&mt('Ascending'),                    .' '
                                                        desc=>&mt('Descending')                    .&Apache::loncommon::select_form($env{'form.sortorder'},
                                                        ))                                                     'sortorder',
                        );                                                     {asc =>&mt('Ascending'),
     ##                                                      desc=>&mt('Descending')
     ## Output links (if necessary) for 'prev' and 'next' pages.                                                     },'','','','LC_sortby')
     $r->print                    .'</span>';
         ('<table width="100%"><tr><td width="25%" align="right">'.      ##
          '<nobr>'.$sortform.'</nobr>'.      ## Display links for 'prev' and 'next' pages (if necessary) and Display Options
          '</td><td width="25%" align="right">'.      $r->print('<fieldset>'."\n"
          &prev_next_buttons($min,$env{'form.show'},$total_results).               .'<legend>'.&mt('Display Options').'</legend>'."\n"
          '</td><td align="right">'.               .$sortform
          &viewoptions().'</td></tr></table>'               .' '
          );               .&viewoptions()
                .'</fieldset>'
                .&prev_next_buttons($min,$env{'form.show'},$total_results)
       );
   
     if ($total_results == 0) {      if ($total_results == 0) {
         $r->print('<meta HTTP-EQUIV="Refresh" CONTENT="2" />'.          $r->print('<h1 class="LC_search_results">'.&mt('There are currently no results.').'</h1>'.
                   '<h3>'.&mt('There are currently no results').'.</h3>'.                    '</form></div>'.
                   "</form>".  
   &Apache::loncommon::end_page());    &Apache::loncommon::end_page());
         return;          return;
     } else {      } else {
         $r->print('<center>'.          $r->print('<h1 class="LC_search_results">'.
                   mt('Results [_1] to [_2] out of [_3]',                    mt('Results [_1] to [_2] out of [_3]',
                      $min,$max,$total_results).                       $min,$max,$total_results).
                   "</center>\n");                    "</h1>\n");
     }      }
     ##      ##
     ## Get results from MySQL table      ## Get results from MySQL table
Line 2936  sub display_results { Line 3004  sub display_results {
     if ($area eq 'portfolio') {      if ($area eq 'portfolio') {
         $tabletype = 'portfolio_search';          $tabletype = 'portfolio_search';
     }      }
       $r->print(&Apache::loncommon::start_data_table().
                 &Apache::loncommon::start_data_table_header_row().
                 '<th>'.&mt('Data').'</th>');
       if (($env{'form.viewselect'} eq 'detailedpreview') ||
           ($env{'form.viewselect'} eq 'summarypreview')) {
           $r->print('<th>'.&mt('Preview').'</th>');
       }
       $r->print(&Apache::loncommon::end_data_table_header_row());
     foreach my $row (@Results) {      foreach my $row (@Results) {
         if ($connection->aborted()) {          if ($connection->aborted()) {
             &cleanup();              &cleanup();
             return;              return;
         }          }
         my %Fields = %{&parse_row($tabletype,@$row)};          my %Fields = %{&parse_row($tabletype,@$row)};
         my $output="<p>\n";          my $output;
         if (! defined($Fields{'title'}) || $Fields{'title'} eq '') {          if (! defined($Fields{'title'}) || $Fields{'title'} eq '') {
             $Fields{'title'} = 'Untitled';              $Fields{'title'} = 'Untitled';
         }          }
Line 2951  sub display_results { Line 3027  sub display_results {
         # 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.
         $r->print($output);          $r->print(&Apache::loncommon::start_data_table_row()
                    .'<td>'
                    .$output
                    .'</td>'
                    .&Apache::loncommon::end_data_table_row()
           );
         $r->rflush();          $r->rflush();
     }      }
       $r->print(&Apache::loncommon::end_data_table());
     if (@Results < 1) {      if (@Results < 1) {
         $r->print(&mt("There were no results matching your query"));          $r->print('<p class="LC_info">'
                    .&mt('There were no results matching your query.')
                    .'</p>');
     } else {      } else {
         $r->print          $r->print(
             ('<center>'.              &prev_next_buttons($min,$env{'form.show'},$total_results,
              &prev_next_buttons($min,$env{'form.show'},$total_results,  
                                 "table=".$env{'form.table'}.                                  "table=".$env{'form.table'}.
                                 "&phase=results".                                  "&amp;phase=results".
                                 "&persistent_db_id=".                                  "&amp;persistent_db_id=".
                                 $env{'form.persistent_db_id'})                                  $env{'form.persistent_db_id'})
              ."</center>\n"          );
              );  
     }      }
     $r->print("</form>".&Apache::loncommon::end_page());      $r->print('</form></div>'.&Apache::loncommon::end_page());
     $r->rflush();      $r->rflush();
     untie %groupsearch_db if (tied(%groupsearch_db));      untie %groupsearch_db if (tied(%groupsearch_db));
     return;      return;
Line 2994  sub catalogmode_output { Line 3076  sub catalogmode_output {
         $title=~ s/\'/\\\'/g;          $title=~ s/\'/\\\'/g;
         if ($env{'form.catalogmode'} eq 'interactive') {          if ($env{'form.catalogmode'} eq 'interactive') {
             $output.=<<END               $output.=<<END 
 <font size='-1'><INPUT TYPE="button" NAME="returnvalues" VALUE="SELECT"  <font size='-1'><input type="button" name="returnvalues" value="select"
 onClick="javascript:select_data('$title','$url')">  onclick="javascript:select_data('$title','$url')" />
 </font>  </font>
 END  END
         }          }
Line 3004  END Line 3086  END
         $groupsearch_db{"pre_${fnum}_title"}=$title;          $groupsearch_db{"pre_${fnum}_title"}=$title;
         $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($checkbox_num,$fnum)" />  onclick="javascript:queue($checkbox_num,$fnum)" />
 </font>  </font>
 END  END
     }      }
Line 3174  sub search_results_header { Line 3256  sub search_results_header {
  if (! exists($env{'form.mode'}) || $env{'form.mode'} ne 'edit') {   if (! exists($env{'form.mode'}) || $env{'form.mode'} ne 'edit') {
             $js.=<<SCRIPT;              $js.=<<SCRIPT;
 <script type="text/javascript">  <script type="text/javascript">
   // <![CDATA[
     function select_data(title,url) {      function select_data(title,url) {
  changeTitle(title);   changeTitle(title);
  changeURL(url);   changeURL(url);
Line 3189  sub search_results_header { Line 3272  sub search_results_header {
     parent.opener.inf.document.forms.resinfo.elements.u.value=val;      parent.opener.inf.document.forms.resinfo.elements.u.value=val;
  }   }
     }      }
   // ]]>
 </script>  </script>
 SCRIPT  SCRIPT
         } elsif ($env{'form.mode'} eq 'edit') {          } elsif ($env{'form.mode'} eq 'edit') {
Line 3213  END Line 3297  END
   
             $js.=<<SCRIPT;              $js.=<<SCRIPT;
 <script type="text/javascript">  <script type="text/javascript">
   // <![CDATA[
 function select_data(title,url) {  function select_data(title,url) {
     changeURL(url);      changeURL(url);
     changeTitle(title);      changeTitle(title);
Line 3227  function changeURL(val) { Line 3312  function changeURL(val) {
         alert("Unable to transfer data to "+url);          alert("Unable to transfer data to "+url);
     }      }
 }  }
   // ]]>
 </script>  </script>
 SCRIPT  SCRIPT
         }          }
     }      }
       my $inhibit_menu = "&".&Apache::loncommon::inhibit_menu_check();
     $js.=<<SCRIPT if $env{'form.catalogmode'} eq 'import';      $js.=<<SCRIPT if $env{'form.catalogmode'} eq 'import';
 <script type="text/javascript">  <script type="text/javascript">
   // <![CDATA[
     function queue(checkbox_num,val) {      function queue(checkbox_num,val) {
         if (document.forms.results.returnvalues.length != "undefined" &&          if (document.forms.results.returnvalues.length != "undefined" &&
             typeof(document.forms.results.returnvalues.length) == "number") {              typeof(document.forms.results.returnvalues.length) == "number") {
Line 3251  SCRIPT Line 3339  SCRIPT
     }      }
     function select_group() {      function select_group() {
  parent.window.location=   parent.window.location=
     "/adm/groupsort?mode=$env{'form.mode'}&catalogmode=import&acts="+      "/adm/groupsort?mode=$env{'form.mode'}&catalogmode=import$inhibit_menu&acts="+
     parent.statusframe.document.forms.statusform.elements.acts.value;      parent.statusframe.document.forms.statusform.elements.acts.value;
     }      }
   // ]]>
   </script>
   SCRIPT
   
       $js.=<<SCRIPT;
   <script type="text/javascript">
       \$(document).ready(function() {
           parent.done_loading_results();
       });
 </script>  </script>
 SCRIPT  SCRIPT
   
     my $start_page  = &Apache::loncommon::start_page(undef,$js,      my $start_page  = &Apache::loncommon::start_page(undef,$js,
      {'only_body' =>1});       {'only_body' =>1,
                                                         'add_wishlist' =>1,
                                                         'add_modal' =>1});
     my $result=<<END;      my $result=<<END;
 $start_page  $start_page
   <div class="LC_landmark" role="main">
 <form name="results" method="post" action="/adm/searchcat">  <form name="results" method="post" action="/adm/searchcat">
 $importbutton  $importbutton
 END  END
Line 3268  END Line 3368  END
 }  }
   
 sub results_link {  sub results_link {
     my $basic_link   = "/adm/searchcat?"."&table=".$env{'form.table'}.      my $basic_link   = "/adm/searchcat?"."&amp;table=".$env{'form.table'}.
         "&persistent_db_id=".$env{'form.persistent_db_id'};          "&amp;area=".$env{'form.area'}.
     my $results_link = $basic_link."&phase=results".          "&amp;catalogmode=".$env{'form.catalogmode'}.
         "&pause=1"."&start=1";          "&amp;persistent_db_id=".$env{'form.persistent_db_id'};
       my $results_link = $basic_link."&amp;phase=results".
           "&amp;pause=1"."&amp;start=1";
     return $results_link;      return $results_link;
 }  }
   
Line 3279  sub results_link { Line 3381  sub results_link {
 ######################################################################  ######################################################################
 sub print_frames_interface {  sub print_frames_interface {
     my $r = shift;      my $r = shift;
     my $basic_link = "/adm/searchcat?"."&table=".$env{'form.table'}.      my $basic_link = "/adm/searchcat?table=".$env{'form.table'}.
         "&persistent_db_id=".$env{'form.persistent_db_id'};          "&amp;area=".$env{'form.area'}.
     my $run_search_link = $basic_link."&phase=run_search";          "&amp;catalogmode=".$env{'form.catalogmode'}.
           "&amp;persistent_db_id=".$env{'form.persistent_db_id'};
       my $run_search_link = $basic_link."&amp;phase=run_search";
     my $results_link = &results_link();      my $results_link = &results_link();
     my $js = <<JS;      my $js = <<JS;
 <script type="text/javascript">  <script type="text/javascript">
   // <![CDATA[
 var targetwin = opener;  var targetwin = opener;
 var queue = '';  var queue = '';
   
   var loading_results = true;
   var need_reloading = false;
   var new_location;
   function update_results(newloc) {
       if (loading_results) {
           need_reloading = true;
           new_location = newloc;
       } else {
           loading_results = true;
           resultsframe.location = newloc;
       }
   }
   function done_loading_results() {
       loading_results = false;
       if (need_reloading) {
           need_reloading = false;
           update_results(new_location);
       }
   }
   // ]]>
 </script>  </script>
 JS  JS
   
Line 3348  sub evalfields { Line 3474  sub evalfields {
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
   
   sub display_tools {
       my ($title, $jumpurl) = @_;
       my $result;
       # Metadata
       $result.=
           &Apache::loncommon::modal_link(
               $jumpurl.'.meta?inhibitmenu=yes',
               '<img class="LC_icon" src="/res/adm/pages/catalog.png" alt="Info" />',
               500,500,'_blank',undef,&mt('Metadata'));
       # Stored Links
       $result.=
           ' <a href="javascript:;"'.
           ' onclick="set_wishlistlink('."'$title','$jumpurl'".')" '.
           'title="'.&mt('Save a link for this resource in your personal Stored Links repository').'">'.
           '<img class="LC_icon" src="/res/adm/pages/wishlist.png" '.
           'alt="Stored Links" style="width:22px;"/></a>';
       return $result;
   }
   
   ######################################################################
   ######################################################################
   
 =pod   =pod 
   
 =item Metadata Viewing Functions  =item Metadata Viewing Functions
Line 3372  sub detailed_citation_view { Line 3520  sub detailed_citation_view {
     my $result;      my $result;
     my $jumpurl=$values{'url'};      my $jumpurl=$values{'url'};
     $jumpurl=~s|^/ext/|http://|;      $jumpurl=~s|^/ext/|http://|;
     $result .= '<b>'.$prefix.      $result .=
         '<img src="'.&Apache::loncommon::icon($values{'url'}).'" />'.'&nbsp;'.          '<b>'.$prefix.
         '<a href="'.$jumpurl.'" '.          '<img src="'.&Apache::loncommon::icon($values{'url'}).'" alt="" />'.'&nbsp;'.
         'target="preview">'.$values{'title'}."</a></b>\n";          '<a href="'.$jumpurl.'?inhibitmenu=yes" '.
     $result .= "<p>\n";          'target="preview" onclick="openMyModal(this.href, 500, 500, \'yes\');return false;">'.$values{'title'}."</a></b>\n".
     $result .= '<b>'.$values{'author'}.'</b>,'.          &display_tools($values{'title'}, $jumpurl).
           "<p>\n".
           '<b>'.$values{'author'}.'</b>,'.
         ' <i>'.$values{'owner'}.'</i><br />';          ' <i>'.$values{'owner'}.'</i><br />';
     foreach my $field       foreach my $field 
         (          (
Line 3441  sub detailed_citation_view { Line 3591  sub detailed_citation_view {
         if (exists($field->{'type'}) && $field->{'type'} eq 'list') {          if (exists($field->{'type'}) && $field->{'type'} eq 'list') {
             $result .= '<b>'.&mt($field->{'translate'}).'</b>';              $result .= '<b>'.&mt($field->{'translate'}).'</b>';
             foreach my $item (split(',',$values{$field->{'name'}})){              foreach my $item (split(',',$values{$field->{'name'}})){
                 $result .=                   $item = &Apache::lonnet::clutter($item);
   &Apache::lonhtmlcommon::crumbs(&Apache::lonnet::clutter($item),                  $result .= '<br />'.&display_url($item,1).'<br />';
   'preview',  
   '',  
   (($env{'form.catalogmode'} eq 'import')?'parent.statusframe.document.forms.statusform':''),2,0,1);  
             }              }
         } elsif (exists($field->{'format'}) && $field->{'format'} ne ''){          } elsif (exists($field->{'format'}) && $field->{'format'} ne ''){
             $result.= &mt($field->{'translate'},              $result.= &mt($field->{'translate'},
Line 3453  sub detailed_citation_view { Line 3600  sub detailed_citation_view {
                                   $values{$field->{'name'}}))."<br />\n";                                    $values{$field->{'name'}}))."<br />\n";
         } else {          } else {
             if ($field->{'special'} eq 'url link') {              if ($field->{'special'} eq 'url link') {
                if ($jumpurl=~/^http\:\/\//) {                  $result .= '<br />'.&display_url($jumpurl,1).'<br />';
                  $result.='<tt>'.$jumpurl.'</tt>';  
                } else {  
                  $result .=  
   &Apache::lonhtmlcommon::crumbs($jumpurl,  
   'preview',  
   '',  
   (($env{'form.catalogmode'} eq 'import')?'parent.statusframe.document.forms.statusform':''),3,0,1);  
                }  
             } else {              } else {
                 $result.= &mt($field->{'translate'},                  $result.= &mt($field->{'translate'},
                               $values{$field->{'name'}});                                $values{$field->{'name'}});
Line 3476  sub detailed_citation_view { Line 3615  sub detailed_citation_view {
     if (exists($values{'shortabstract'}) && $values{'shortabstract'} ne '') {      if (exists($values{'shortabstract'}) && $values{'shortabstract'} ne '') {
         $result .= '<p>'.$values{'shortabstract'}.'</p>';          $result .= '<p>'.$values{'shortabstract'}.'</p>';
     }      }
     $result .= '<hr align="left" width="200" noshade />'."\n";  
     return $result;      return $result;
 }  }
   
 sub detailed_citation_preview {  sub detailed_citation_preview {
     my ($prefix,%values)=@_;      my ($prefix,%values)=@_;
     return '<table><tr><td>'.      return &detailed_citation_view($prefix,%values).
            &detailed_citation_view($prefix,%values).  
            '</td><td>'.             '</td><td>'.
            &Apache::lonindexer::showpreview($values{'url'}).             &Apache::lonindexer::showpreview($values{'url'});
            '</td></tr></table><hr />';  
 }  }
   
   
Line 3503  sub detailed_citation_preview { Line 3639  sub detailed_citation_preview {
 sub summary_view {  sub summary_view {
     my ($prefix,%values) = @_;      my ($prefix,%values) = @_;
     my $icon=&Apache::loncommon::icon($values{'url'});      my $icon=&Apache::loncommon::icon($values{'url'});
     my $result=qq{$prefix<img src="$icon" />};      my $result=qq{$prefix<img src="$icon" alt="" />};
     if (exists($env{'form.sortfield'}) &&       if (exists($env{'form.sortfield'}) && 
         $env{'form.sortfield'} !~ /^(default|          $env{'form.sortfield'} !~ /^(default|
                                      author|                                       author|
Line 3517  sub summary_view { Line 3653  sub summary_view {
         $result .= '&nbsp;'.$tmp.'&nbsp;';          $result .= '&nbsp;'.$tmp.'&nbsp;';
     }      }
     my $jumpurl=$values{'url'};      my $jumpurl=$values{'url'};
     my $link;      $jumpurl=~s|^/ext/|http://|;
     if ($jumpurl=~m|^/ext/|) {      my $link = '<br />'.&display_url($jumpurl,1).'<br />';
  $jumpurl=~s|^/ext/|http://|;      $result .=
  $link='<br /><tt>'.$jumpurl.'</tt>';          '<a href="'.$jumpurl.'?inhibitmenu=yes"'.
     } else {          ' target="preview" onclick="openMyModal(this.href, 500, 500, \'yes\');return false;">'.$values{'title'}.'</a>'.
  $link=&Apache::lonhtmlcommon::crumbs($jumpurl,          &display_tools($values{'title'}, $jumpurl).<<END;
   'preview',  <br />
   '',  $link<br />
   (($env{'form.catalogmode'} eq 'import')?'parent.statusframe.document.forms.statusform':''),2,0,1);  
     }  
     $result.=<<END;  
 <a href="$jumpurl"   
    target='preview'>$values{'title'}</a>$link  
 $values{'author'}, $values{'owner'} -- $values{'lastrevisiondate'}<br />  $values{'author'}, $values{'owner'} -- $values{'lastrevisiondate'}<br />
 $values{'copyrighttag'}<br />  $values{'copyrighttag'}<br />
 $values{'extrashow'}  $values{'extrashow'}
 </p>  
 <hr align='left' width='200' noshade />  
 END  END
     return $result;      return $result;
 }  }
   
 sub summary_preview {  sub summary_preview {
     my ($prefix,%values)=@_;      my ($prefix,%values)=@_;
     return '<table><tr><td>'.      return &summary_view($prefix,%values).
            &summary_view($prefix,%values).  
            '</td><td>'.             '</td><td>'.
            &Apache::lonindexer::showpreview($values{'url'}).             &Apache::lonindexer::showpreview($values{'url'});
            '</td></tr></table><hr />';  
 }  }
   
 ######################################################################  ######################################################################
Line 3562  sub summary_preview { Line 3689  sub summary_preview {
 sub compact_view {  sub compact_view {
     my ($prefix,%values) = @_;      my ($prefix,%values) = @_;
     my $jumpurl=$values{'url'};      my $jumpurl=$values{'url'};
     my $link;      $jumpurl=~s|^/ext/|http://|;
     if ($jumpurl=~m|^/ext/|) {  
  $jumpurl=~s|^/ext/|http://|;      my $link = &display_url($jumpurl,1);
  $link='<tt>'.$jumpurl.'</tt>';      
     } else {  
         $link=&Apache::lonhtmlcommon::crumbs($jumpurl,  
   'preview',  
   '',  
   (($env{'form.catalogmode'} eq 'import')?'parent.statusframe.document.forms.statusform':''),1,1,1).' ';  
     }  
     my $result =       my $result = 
         $prefix.'<img src="'.&Apache::loncommon::icon($values{'url'}).'">';          $prefix.'<img src="'.&Apache::loncommon::icon($values{'url'}).'" alt="" />';
     if (exists($env{'form.sortfield'}) &&       if (exists($env{'form.sortfield'}) && 
         $env{'form.sortfield'} !~ /^(default|author|url|title)$/) {          $env{'form.sortfield'} !~ /^(default|author|url|title)$/) {
         my $tmp = $values{$env{'form.sortfield'}};          my $tmp = $values{$env{'form.sortfield'}};
         if (! defined($tmp)) { $tmp = 'undefined'; }          if (! defined($tmp)) { $tmp = 'undefined'; }
         $result .= '&nbsp;'.$tmp.'&nbsp;';          $result .= '&nbsp;'.$tmp.'&nbsp;';
     }      }
     $result.='&nbsp;<a href="'.$jumpurl.'" target="preview">'.      $jumpurl = &HTML::Entities::encode($jumpurl,'<>&"');
         $values{'title'}.'</a>'.('&nbsp;'x2).$link.      $result.=' <span class="LC_nobreak">'.
         '<b>'.$values{'author'}.'</b> ('.$values{'domain'}.')<br />';   '<a href="'.$jumpurl.'?inhibitmenu=yes" target="preview" onclick="openMyModal(this.href, 500, 500, \'yes\');return false;">'.
           &HTML::Entities::encode($values{'title'},'<>&"').'</a></span> '.
           &display_tools($values{'title'}, $jumpurl).
    $link.' <b>'.$values{'author'}.'</b> ('.$values{'domain'}.')';
     return $result;      return $result;
 }  }
   
   sub display_url {
       my ($url,$skiplast) = @_;
       my $link;
       if ($url=~m|^/ext/|) {
    $url=~s|^/ext/|http://|;
    $link='<span class="LC_filename">'.$url.'</span>';
       } elsif ($url=~m{^(http://|/uploaded/)}) {
    $link='<span class="LC_filename">'.$url.'</span>';
       } else {
           # replace the links to open in a new window
           # (because the search opens in a new window, it gets
           # confusing when the links open a tab in the
           # parent window; ideally we should not force windows)
           my $onclick = " onclick=\"window.open(this.href, '_blank', 'toolbar=1,location=1,menubar=0');return false;\""; 
           $link=&Apache::lonhtmlcommon::crumbs(
                     $url,
                     'preview',
                     '',
                     '',
                     $skiplast,$onclick).' ';
       }
       return $link;
   }
   
 ######################################################################  ######################################################################
 ######################################################################  ######################################################################
Line 3606  sub fielded_format_view { Line 3753  sub fielded_format_view {
     $jumpurl=~s|^/ext/|http://|;      $jumpurl=~s|^/ext/|http://|;
   
     my $result=<<END;      my $result=<<END;
 $prefix <img src="$icon" />  $prefix <img src="$icon" alt="" />
 <dl>  <dl>
 <dt>URL:</dt>  <dt>URL:</dt>
     <dd><a href="$jumpurl"       <dd><a href="$jumpurl?inhibitmenu=yes" 
          target='preview'>$values{'url'}</a></dd>           target='preview'>$values{'url'}</a>
 END  END
       $result .=
           &display_tools($values{'title'}, $jumpurl).'
       </dd>';
     foreach my $field ('title','author','domain','subject','keywords','notes',      foreach my $field ('title','author','domain','subject','keywords','notes',
                        'mimetag','language','creationdate','lastrevisiondate',                         'mimetag','language','creationdate','lastrevisiondate',
                        'owner','copyrighttag','hostname','abstract') {                         'owner','copyrighttag','hostname','abstract') {
Line 3632  END Line 3782  END
     }      }
     $result .= "</dl>\n";      $result .= "</dl>\n";
     $result .= $values{'extrashow'};      $result .= $values{'extrashow'};
     $result .= '<hr align="left" width="200" noshade />'."\n";  
     return $result;      return $result;
 }  }
   
Line 3706  $prefix Line 3855  $prefix
 $xml  $xml
 </pre>  </pre>
 $values{'extrashow'}  $values{'extrashow'}
 <hr align='left' width='200' noshade />  
 END  END
     return $result;      return $result;
 }  }
Line 3746  sub output_unparsed_phrase_error { Line 3894  sub output_unparsed_phrase_error {
     my ($r,$closebutton,$parms,$hidden_fields,$field)=@_;      my ($r,$closebutton,$parms,$hidden_fields,$field)=@_;
     my $errorstring;      my $errorstring;
     if ($field eq 'basicexp') {      if ($field eq 'basicexp') {
         $errorstring = &mt('Unable to understand the search phrase <i>[_1]</i>.  Please modify your search.',$env{'form.basicexp'});          $errorstring = &mt('Unable to understand the search phrase [_1]. Please modify your search.'
                              ,'<i>'.$env{'form.basicexp'}.'</i>');
     } else {      } else {
         $errorstring = &mt('Unable to understand the search phrase <b>[_1]</b>:<i>[_2]</i>.',$field,$env{'form.'.$field});          $errorstring = &mt('Unable to understand the search phrase [_1]: [_2]'
                              ,'<i>'.$field.'</i>'
                              ,$env{'form.'.$field});
     }      }
     my $heading = &mt('Unparsed Field');      my $heading = &mt('Unparsed Field');
     my $revise  = &mt('Revise search request');      my $revise  = &mt('Revise search request');
Line 3762  $hidden_fields Line 3913  $hidden_fields
 $closebutton  $closebutton
 <hr />  <hr />
 <h2>$heading</h2>  <h2>$heading</h2>
 <p>  <p class="LC_warning">
 $errorstring  $errorstring
 </p>  </p>
 <p>  <p>
 <a href="/adm/searchcat?$parms&persistent_db_id=$env{'form.persistent_db_id'}">$revise</a>  <a href="/adm/searchcat?$parms&amp;persistent_db_id=$env{'form.persistent_db_id'}">$revise</a>
 </p>  </p>
 $end_page  $end_page
 ENDPAGE  ENDPAGE
Line 3794  $parms is extra information to include i Line 3945  $parms is extra information to include i
 ######################################################################  ######################################################################
 sub output_blank_field_error {  sub output_blank_field_error {
     my ($r,$closebutton,$parms,$hidden_fields)=@_;      my ($r,$closebutton,$parms,$hidden_fields)=@_;
     my $errormsg = &mt('You did not fill in enough information for the search to be started.  You need to fill in relevant fields on the search page in order for a query to be processed.');      my $errormsg = &mt('You did not fill in enough information for the search to be started. You need to fill in relevant fields on the search page in order for a query to be processed.');
     my $revise = &mt('Revise Search Request');      my $revise = &mt('Revise Search Request');
     my $heading = &mt('Unactionable Search Queary');      my $heading = &mt('Unactionable Search Query');
     my $start_page = &Apache::loncommon::start_page('Search');      my $start_page = &Apache::loncommon::start_page('Search');
     my $end_page   = &Apache::loncommon::end_page();      my $end_page   = &Apache::loncommon::end_page();
       if ($closebutton) {
           $closebutton = '<p>'.$closebutton.'</p><hr />';
       } else {
           &Apache::lonhtmlcommon::add_breadcrumb
               ({href=>'',
                 text=>$heading,});
           $start_page .= &Apache::lonhtmlcommon::breadcrumbs();
       }
   
     $r->print(<<ENDPAGE);      $r->print(<<ENDPAGE);
 $start_page  $start_page
 <form method="post" action="/adm/searchcat">  <form method="post" action="/adm/searchcat">
 $hidden_fields  $hidden_fields
 $closebutton  $closebutton
 <hr />  </form>
 <h2>$heading</h2>  <h2>$heading</h2>
 <p>  <p class="LC_warning">
 $errormsg  $errormsg
 </p>  </p>
 <p>  <p>
 <a href="/adm/searchcat?$parms&persistent_db_id=$env{'form.persistent_db_id'}">$revise</a>&nbsp;  <a href="/adm/searchcat?$parms&amp;persistent_db_id=$env{'form.persistent_db_id'}">$revise</a>
 </p>  </p>
 $end_page  $end_page
 ENDPAGE  ENDPAGE
Line 3841  sub output_date_error { Line 4001  sub output_date_error {
     # make query information persistent to allow for subsequent revision      # make query information persistent to allow for subsequent revision
     my $start_page = &Apache::loncommon::start_page('Search');      my $start_page = &Apache::loncommon::start_page('Search');
     my $end_page   = &Apache::loncommon::end_page();      my $end_page   = &Apache::loncommon::end_page();
       my $heading = &mt('Error');
     $r->print(<<RESULTS);      $r->print(<<RESULTS);
 $start_page  $start_page
 <form method="post" action="/adm/searchcat">  <form method="post" action="/adm/searchcat">
 $hidden_fields  $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
   </form>
 <hr />  <hr />
 <h3>Error</h3>  <h3>$heading</h3>
 <p>  <p class="LC_error">
 $message  $message
 </p>  </p>
 $end_page  $end_page
Line 3873  Cleans the global %groupsearch_db by rem Line 4035  Cleans the global %groupsearch_db by rem
 ######################################################################  ######################################################################
 sub start_fresh_session {  sub start_fresh_session {
     delete $groupsearch_db{'mode_catalog'};      delete $groupsearch_db{'mode_catalog'};
     foreach (keys %groupsearch_db) {      foreach (keys(%groupsearch_db)) {
         if ($_ =~ /^pre_/) {          if ($_ =~ /^pre_/) {
             delete $groupsearch_db{$_};              delete $groupsearch_db{$_};
         }          }
Line 3891  sub cleanup { Line 4053  sub cleanup {
   &Apache::lonnet::logthis('Failed cleanup searchcat: groupsearch_db');    &Apache::lonnet::logthis('Failed cleanup searchcat: groupsearch_db');
         }          }
     }      }
     &untiehash();  
     &Apache::lonmysql::disconnect_from_db();      &Apache::lonmysql::disconnect_from_db();
     return OK;      return OK;
 }  }

Removed from v.1.282  
changed lines
  Added in v.1.363


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