--- loncom/interface/lonsearchcat.pm 2002/09/16 20:57:28 1.158 +++ loncom/interface/lonsearchcat.pm 2003/12/16 15:00:56 1.195 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Search Catalog # -# $Id: lonsearchcat.pm,v 1.158 2002/09/16 20:57:28 matthew Exp $ +# $Id: lonsearchcat.pm,v 1.195 2003/12/16 15:00:56 matthew Exp $ # # Copyright Michigan State University Board of Trustees # @@ -74,15 +74,15 @@ package Apache::lonsearchcat; # ------------------------------------------------- modules used by this module use strict; -use Apache::Constants qw(:common); +use Apache::Constants qw(:common :http); use Apache::lonnet(); use Apache::File(); use CGI qw(:standard); use Text::Query; -use DBI; use GDBM_File; use Apache::loncommon(); use Apache::lonmysql(); +use Apache::lonlocal; # ---------------------------------------- variables used throughout the module @@ -143,6 +143,14 @@ my %persistent_db; my $hidden_fields; my $bodytag; +# +# For course search +# +my %alreadyseen; +my $hashtied; +my %hash; +my $totalfound; + ###################################################################### ###################################################################### @@ -179,7 +187,7 @@ sub handler { # This button is different for the RAT compared to # normal invocation. # - $r->content_type('text/html'); + &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK if $r->header_only; ## @@ -192,7 +200,7 @@ sub handler { &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['catalogmode','launch','acts','mode','form','element','pause', 'phase','persistent_db_id','table','start','show', - 'cleargroupsort']); + 'cleargroupsort','titleelement']); ## ## The following is a trick - we wait a few seconds if asked to so ## the daemon running the search can get ahead of the daemon @@ -200,15 +208,14 @@ sub handler { ## this once, so the pause indicator is deleted ## if (exists($ENV{'form.pause'})) { - sleep(3); + sleep(1); delete($ENV{'form.pause'}); } ## ## Initialize global variables ## my $domain = $r->dir_config('lonDefDomain'); - $diropendb= "/home/httpd/perl/tmp/".&Apache::lonnet::escape($domain). - "\_".&Apache::lonnet::escape($ENV{'user.name'})."_searchcat.db"; + $diropendb= "/home/httpd/perl/tmp/$ENV{'user.domain'}_$ENV{'user.name'}_searchcat.db"; # # set the name of the persistent database # $ENV{'form.persistent_db_id'} can only have digits in it. @@ -275,6 +282,10 @@ END $hidden_fields .= ''."\n"; } + if (exists($ENV{'form.titleelement'})) { + $hidden_fields .= ''."\n"; + } if (exists($ENV{'form.mode'})) { $hidden_fields .= ''."\n"; @@ -339,6 +350,8 @@ END &run_search($r,$query,$customquery,$customshow, $libraries,$pretty_string); } + } elsif ($ENV{'form.phase'} eq 'course_search') { + &course_search($r); } elsif(($ENV{'form.phase'} eq 'basic_search') || ($ENV{'form.phase'} eq 'adv_search')) { $ENV{'form.searchmode'} = 'basic'; @@ -374,7 +387,8 @@ END (undef,undef,undef,undef); my $pretty_string; if ($ENV{'form.phase'} eq 'basic_search') { - ($query,$pretty_string) = &parse_basic_search($r,$closebutton); + ($query,$pretty_string,$libraries) = + &parse_basic_search($r,$closebutton); } else { # Advanced search ($query,$customquery,$customshow,$libraries,$pretty_string) = &parse_advanced_search($r,$closebutton); @@ -397,6 +411,111 @@ END ###################################################################### ###################################################################### +sub course_search { + my $r=shift; + my $bodytag=&Apache::loncommon::bodytag('Course Search'); + my $pretty_search_string = ''.$ENV{'form.courseexp'}.''; + my $search_string = $ENV{'form.courseexp'}; + my @New_Words; + if ($ENV{'form.crsrelated'}) { + ($search_string,@New_Words) = &related_version($ENV{'form.courseexp'}); + if (@New_Words) { + $pretty_search_string .= " with related words: @New_Words."; + } else { + $pretty_search_string .= " with no related words."; + } + } + my $fulltext=$ENV{'form.crsfulltext'}; + my @allwords=($search_string,@New_Words); + $totalfound=0; + $r->print('LON-CAPA Course Search'. + $bodytag.$pretty_search_string); + $r->rflush(); +# ======================================================= Go through the course + $hashtied=0; + undef %alreadyseen; + %alreadyseen=(); + my $c=$r->connection; + &tiehash(); + foreach (keys %hash) { + if ($c->aborted()) { last; } + if (($_=~/^src\_(.+)$/) && (!$alreadyseen{$hash{$_}})) { + &checkonthis($r,$hash{$_},0,$hash{'title_'.$1},$fulltext,@allwords); + } + } + &untiehash(); + unless ($totalfound) { + $r->print('

'.&mt('No resources found').'.

'); + } +# =================================================== Done going through course + $r->print(''); +} + +# ---------------------------------------------------------------- tie the hash + +sub tiehash { + $hashtied=0; + if ($ENV{'request.course.fn'}) { + if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.".db", + &GDBM_READER(),0640)) { + $hashtied=1; + } + } +} + +sub untiehash { + if ($hashtied) { untie %hash; } + $hashtied=0; +} + +# =============================== This pulls up a resource and its dependencies + +sub checkonthis { + my ($r,$url,$level,$title,$fulltext,@allwords)=@_; + $alreadyseen{$url}=1; + $r->rflush(); + my $result=&Apache::lonnet::metadata($url,'title').' '. + &Apache::lonnet::metadata($url,'subject').' '. + &Apache::lonnet::metadata($url,'abstract').' '. + &Apache::lonnet::metadata($url,'keywords'); + if (($url) && ($fulltext)) { + $result.=&Apache::lonnet::ssi_body($url); + } + $result=~s/\s+/ /gs; + my $applies=0; + foreach (@allwords) { + if ($_=~/\w/) { + if ($result=~/$_/si) { + $applies++; + } + } + } +# Does this resource apply? + if ($applies) { + $r->print('
'); + for (my $i=0;$i<=$level*5;$i++) { + $r->print(' '); + } + $r->print(''. + ($title?$title:$url).'
'); + $totalfound++; + } elsif ($fulltext) { + $r->print(' .'); + } + $r->rflush(); +# Check also the dependencies of this one + my $dependencies= + &Apache::lonnet::metadata($url,'dependencies'); + foreach (split(/\,/,$dependencies)) { + if (($_=~/^\/res\//) && (!$alreadyseen{$_})) { + &checkonthis($r,$_,$level+1,'',$fulltext,@allwords); + } + } +} + +###################################################################### +###################################################################### + =pod =item &print_basic_search_form() @@ -410,7 +529,7 @@ Returns a scalar which holds html for th sub print_basic_search_form{ my ($r,$closebutton) = @_; - my $bodytag=&Apache::loncommon::bodytag('Catalog Search'); + my $bodytag=&Apache::loncommon::bodytag('Search'); my $scrout=<<"ENDDOCUMENT"; @@ -424,12 +543,17 @@ sub print_basic_search_form{ $bodytag -
+ENDDOCUMENT +if (&Apache::lonnet::allowed('bre',$ENV{'request.role.domain'})) { + my $CatalogSearch=&mt('Catalog Search'); + my $Statement=&mt('Enter terms or phrases separated by AND, OR, or NOT then press SEARCH below'); + $scrout.=(<$CatalogSearch + $hidden_fields

-Enter terms or phrases separated by AND, OR, or NOT -then press SEARCH below. +$Statement.

@@ -437,28 +561,73 @@ then press SEARCH below. ENDDOCUMENT $scrout.=' '.&simpletextfield('basicexp',$ENV{'form.basicexp'},40). ' '; - my $checkbox = &simplecheckbox('related',$ENV{'form.related'}); + my $relatedcheckbox = &simplecheckbox('related',$ENV{'form.related'}); + my $domain = $r->dir_config('lonDefDomain'); + my $domaincheckbox = &simplecheckbox('domains',$domain); + my $srch=&mt('Search'); + my $header=&mt('Advanced Search'); + my $userelatedwords=&mt('use related words'); + my $onlysearchdomain=&mt('only search domain'); $scrout.=< - + + +
Advanced Search
$checkbox use related words
$header
$relatedcheckbox $userelatedwords$domaincheckbox $onlysearchdomain $domain

  +   $closebutton END - $scrout.=&selectbox(undef,'viewselect', + $scrout.=&selectbox('View','viewselect', $ENV{'form.viewselect'}, undef,undef,undef, sort(keys(%Views))); - $scrout.=&selectbox(undef,'show', + $scrout.=&selectbox('Per Page','show', $ENV{'form.show'}, undef,undef,undef, (10,20,50,100)); $scrout.=< +ENDDOCUMENT + } + if ($ENV{'request.course.id'}) { + my %lt=&Apache::lonlocal::texthash( + 'srch' => 'Search', + 'header' => 'Course Search', + 'note' => 'Enter terms or phrases, then press "Search" below', + ); + $scrout.=(< +

$lt{'header'}

+
+ +$hidden_fields +

+$lt{'note'}. +

+

+ + + + +
+ENDCOURSESEARCH + $scrout.=' '. + &simpletextfield('courseexp',$ENV{'form.courseexp'},40); + my $crscheckbox = + &simplecheckbox('crsfulltext',$ENV{'form.crsfulltext'}); + my $relcheckbox = + &simplecheckbox('crsrelated',$ENV{'form.crsrelated'}); + $scrout.=(<
$relcheckbox use related words
$crscheckbox fulltext search (time consuming)

+

+ENDENDCOURSE + } + $scrout.=(< ENDDOCUMENT @@ -526,8 +695,8 @@ ENDHEADER undef,undef,undef, (10,20,50,100)); $scrout.=' '. - 'Per Page'; - $scrout.="Related
Words\n"; + ''.&mt('Per Page').''; + $scrout.="".&mt('Related').'
'.&mt('Words')."\n"; $scrout.=&searchphrasefield_with_related('title', 'title' , $ENV{'form.title'}); $scrout.=&searchphrasefield('author', 'author' ,$ENV{'form.author'}); @@ -542,13 +711,13 @@ ENDHEADER $ENV{'form.abstract'}); # Hack - an empty table row. $scrout.="   \n"; - $scrout.=&searchphrasefield('file
extension','mime', - $ENV{'form.mime'}); + $scrout.=&searchphrasefield('file
extension','extension', + $ENV{'form.extension'}); $scrout.="   \n"; $scrout.=&searchphrasefield('publisher
owner','owner', $ENV{'form.owner'}); $scrout.="\n"; - $ENV{'form.category'}='any' unless length($ENV{'form.category'}); + $ENV{'form.category'}='any' if (! defined($ENV{'form.category'})); $scrout.=&selectbox('File Category','category', $ENV{'form.category'}, 'any','Any category', @@ -569,9 +738,9 @@ ENDHEADER my @domains =&Apache::loncommon::get_domains(); # adjust the size of the select box my $size = 4; - my $size = (scalar @domains < ($size - 1) ? scalar @domains + 1 : $size); + $size = (scalar @domains < ($size - 1) ? scalar @domains + 1 : $size); $scrout.="\n".''. - 'DOMAINS
'. + 'DOMAINS TO BE SEARCHED
'. ''; +sub simplecheckbox{ + my ($name,$value,$checked)=@_; + $checked="checked" if ($value eq 'on'); + return ''; } ############################################### @@ -894,7 +1071,7 @@ field heading. ############################################### sub fieldtitle { - my $title = uc(shift()); + my $title = uc(&mt(shift())); return ''.$title. ': '; } @@ -989,7 +1166,7 @@ END my $i = 1; foreach (qw/January February March April May June July August September October November December /){ - $month .="\n"; + $month .="\n"; $i++; } $month.="\n"; @@ -1066,6 +1243,7 @@ sub selectbox { my ($title,$name,$default,$anyvalue,$anytag,$functionref,@idlist)=@_; if (! defined($functionref)) { $functionref = sub { $_[0]}; } my $selout=''; + $title=&mt($title); if (defined($title)) { my $uctitle=uc($title); $selout="\n".'

'. @@ -1076,12 +1254,12 @@ sub selectbox { foreach (@idlist) { $selout.=''; } elsif ($_ eq $default and /^$anyvalue$/) { - $selout.=' selected >'.$anytag.''; + $selout.=' selected >'.&mt($anytag).''; } - else {$selout.='>'.&{$functionref}($_).'';} + else {$selout.='>'.&mt(&{$functionref}($_)).'';} } return $selout.''.(defined($title)?'

':' '); } @@ -1134,7 +1312,7 @@ sub parse_advanced_search { 'lastrevisiondatestart_month','lastrevisiondatestart_day', 'lastrevisiondatestart_year','lastrevisiondateend_month', 'lastrevisiondateend_day','lastrevisiondateend_year', - 'notes','abstract','mime','language','owner', + 'notes','abstract','extension','language','owner', 'custommetadata','customshow','category') { $ENV{"form.$field"}=~s/[^\w\/\s\(\)\=\-\"\']//g; } @@ -1145,16 +1323,13 @@ sub parse_advanced_search { $ENV{"form.$_"}=~s/[^\w\/\s\(\)\=\-\"\']//g; } # Preprocess the category form element. - $ENV{'form.category'} = 'any' if (ref($ENV{'form.category'})); - if ($ENV{'form.category'} ne 'any') { - my @extensions = &Apache::loncommon::filecategorytypes - ($ENV{'form.category'}); - $ENV{'form.mime'} = join ' OR ',@extensions; - } + $ENV{'form.category'} = 'any' if (! defined($ENV{'form.category'}) || + ref($ENV{'form.category'})); + # # Check to see if enough information was filled in for my $field ('title','author','subject','keywords','url','version', - 'notes','abstract','mime','language','owner', - 'custommetadata') { + 'notes','abstract','category','extension','language', + 'owner','custommetadata') { if (&filled($ENV{"form.$field"})) { $fillflag++; } @@ -1169,7 +1344,7 @@ sub parse_advanced_search { my $font = ''; # Evaluate logical expression AND/OR/NOT phrase fields. foreach my $field ('title','author','subject','notes','abstract','url', - 'keywords','version','owner','mime') { + 'keywords','version','owner') { if ($ENV{'form.'.$field}) { my $searchphrase = $ENV{'form.'.$field}; $pretty_search_string .= $font."$field contains ". @@ -1188,10 +1363,30 @@ sub parse_advanced_search { push @queries,&build_SQL_query($field,$searchphrase); } } - # I dislike the hack below. - if ($ENV{'form.category'}) { - $ENV{'form.mime'}=''; + # + # Make the 'mime' from 'form.category' and 'form.extension' + # + my $searchphrase; + if (exists($ENV{'form.category'}) && + $ENV{'form.category'} !~ /^\s*$/ && + $ENV{'form.category'} ne 'any') { + my @extensions = &Apache::loncommon::filecategorytypes + ($ENV{'form.category'}); + if (scalar(@extensions) > 0) { + $searchphrase = join(' OR ',@extensions); + } + } + if (exists($ENV{'form.extension'}) && $ENV{'form.extension'} !~ /^\s*$/) { + $searchphrase .= ' OR ' if (defined($searchphrase)); + my @extensions = split(/,/,$ENV{'form.extension'}); + $searchphrase .= join(' OR ',@extensions); + } + if (defined($searchphrase)) { + push @queries,&build_SQL_query('mime',$searchphrase); + $pretty_search_string .=$font.'mime contains '. + $searchphrase.'
'; } + ##### # Evaluate option lists if ($ENV{'form.language'} and $ENV{'form.language'} ne 'any') { push @queries,"(language like \"$ENV{'form.language'}\")"; @@ -1250,11 +1445,33 @@ sub parse_advanced_search { ## --------------------------------------------------------------- ## Deal with restrictions to given domains ## + my ($libraries_to_query,$pretty_domains_string) = + &parse_domain_restrictions(); + $pretty_search_string .= $pretty_domains_string."
\n"; + # + if (@queries) { + $query=join(" AND ",@queries); + $query="select * from metadata where $query"; + } elsif ($customquery) { + $query = ''; + } + return ($query,$customquery,$customshow,$libraries_to_query, + $pretty_search_string); +} + +sub parse_domain_restrictions { my $libraries_to_query = undef; # $ENV{'form.domains'} can be either a scalar or an array reference. # We need an array. - my @allowed_domains = (ref($ENV{'form.domains'}) ? @{$ENV{'form.domains'}} - : ($ENV{'form.domains'}) ); + if (! exists($ENV{'form.domains'})) { + return (undef,''); + } + my @allowed_domains; + if (ref($ENV{'form.domains'})) { + @allowed_domains = @{$ENV{'form.domains'}}; + } else { + @allowed_domains = ($ENV{'form.domains'}); + } my %domain_hash = (); my $pretty_domains_string; foreach (@allowed_domains) { @@ -1277,16 +1494,7 @@ sub parse_advanced_search { } } } - $pretty_search_string .= $pretty_domains_string."
\n"; - # - if (@queries) { - $query=join(" AND ",@queries); - $query="select * from metadata where $query"; - } elsif ($customquery) { - $query = ''; - } - return ($query,$customquery,$customshow,$libraries_to_query, - $pretty_search_string); + return ($libraries_to_query,$pretty_domains_string); } ###################################################################### @@ -1314,7 +1522,8 @@ sub parse_basic_search { $ENV{"form.$_"}=&Apache::lonnet::unescape($ENV{"form.$_"}); $ENV{"form.$_"}=~s/[^\w\/\s\(\)\=\-\"\']//g; } - + my ($libraries_to_query,$pretty_domains_string) = + &parse_domain_restrictions(); # Check to see if enough is filled in unless (&filled($ENV{'form.basicexp'})) { &output_blank_field_error($r,$closebutton,'phase=disp_basic'); @@ -1333,13 +1542,19 @@ sub parse_basic_search { } # Build SQL query string based on form page my $query=''; - my $concatarg=join('," ",', + my $concatarg=join(',', ('title', 'author', 'subject', 'notes', 'abstract', 'keywords')); $concatarg='title' if $ENV{'form.titleonly'}; - $query=&build_SQL_query('concat('.$concatarg.')',$search_string); + $query=&build_SQL_query('concat_ws(" ",'.$concatarg.')',$search_string); + if (defined($pretty_domains_string) && $pretty_domains_string ne '') { + $pretty_search_string .= ' '.$pretty_domains_string; + } $pretty_search_string .= "
\n"; - return 'select * from metadata where '.$query,$pretty_search_string; + my $final_query = 'SELECT * FROM metadata WHERE '.$query; +# &Apache::lonnet::logthis($final_query); + return ($final_query,$pretty_search_string, + $libraries_to_query); } @@ -1452,30 +1667,26 @@ sub recursive_SQL_query_build { my @matches=($pattern=~/(\[[^\]|\[]*\])/g); return $pattern unless @matches; foreach my $match (@matches) { - $match=~/\[ (\w+)\s(.*) \]/; - my ($key,$value)=($1,$2); - my $replacement=''; - if ($key eq 'literal') { - $replacement="($dkey like \"\%$value\%\")"; - } - elsif ($key eq 'not') { - $value=~s/like/not like/; -# $replacement="($dkey not like $value)"; - $replacement="$value"; - } - elsif ($key eq 'and') { - $value=~/(.*[\"|\)]) ([|\(|\^].*)/; - $replacement="($1 AND $2)"; - } - elsif ($key eq 'or') { - $value=~/(.*[\"|\)]) ([|\(|\^].*)/; - $replacement="($1 OR $2)"; + $match=~/\[ (\w+)\s(.*) \]/; + my ($key,$value)=($1,$2); + my $replacement=''; + if ($key eq 'literal') { + $replacement="($dkey LIKE \"\%$value\%\")"; + } elsif (lc($key) eq 'not') { + $value=~s/LIKE/NOT LIKE/; +# $replacement="($dkey not like $value)"; + $replacement="$value"; + } elsif ($key eq 'and') { + $value=~/(.*[\"|\)]) ([|\(|\^].*)/; + $replacement="($1 AND $2)"; + } elsif ($key eq 'or') { + $value=~/(.*[\"|\)]) ([|\(|\^].*)/; + $replacement="($1 OR $2)"; } substr($pattern, - index($pattern,$match), - length($match), - $replacement - ); + index($pattern,$match), + length($match), + $replacement); } &recursive_SQL_query_build($dkey,$pattern); } @@ -1643,8 +1854,8 @@ sub ensure_db_and_table { sub print_sort_form { my ($r,$pretty_query_string) = @_; ## - my %SortableFields = - (id => 'Default', + my %SortableFields=&Apache::lonlocal::texthash( + id => 'Default', title => 'Title', author => 'Author', subject => 'Subject', @@ -1656,7 +1867,7 @@ sub print_sort_form { copyright => 'Copyright', hostname => 'Host', creationdate => 'Creation Date', - lastrevisiondate => 'Revision Date', + lastrevisiondate => 'Revision Date' ); ## my $table = $ENV{'form.table'}; @@ -1732,37 +1943,31 @@ the following format: =cut -## -## Restrictions: -## columns of type 'text' and 'blob' cannot have defaults. -## columns of type 'enum' cannot be used for FULLTEXT. -## -my @DataOrder = qw/id title author subject url keywords version notes - abstract mime lang owner copyright creationdate lastrevisiondate hostname/; - -my %Datatypes = - ( id =>{ type => 'MEDIUMINT', - restrictions => 'UNSIGNED NOT NULL', - primary_key => 'yes', - auto_inc => 'yes' - }, - title =>{ type=>'TEXT'}, - author =>{ type=>'TEXT'}, - subject =>{ type=>'TEXT'}, - url =>{ type=>'TEXT', - restrictions => 'NOT NULL' }, - keywords =>{ type=>'TEXT'}, - version =>{ type=>'TEXT'}, - notes =>{ type=>'TEXT'}, - abstract =>{ type=>'TEXT'}, - mime =>{ type=>'TEXT'}, - lang =>{ type=>'TEXT'}, - owner =>{ type=>'TEXT'}, - copyright =>{ type=>'TEXT'}, - hostname =>{ type=>'TEXT'}, +##################################################################### +##################################################################### + +my @Datatypes = + ( { name => 'id', + type => 'MEDIUMINT', + restrictions => 'UNSIGNED NOT NULL', + primary_key => 'yes', + auto_inc => 'yes' }, + { name => 'title', type=>'TEXT'}, + { name => 'author', type=>'TEXT'}, + { name => 'subject', type=>'TEXT'}, + { name => 'url', type=>'TEXT', restrictions => 'NOT NULL' }, + { name => 'keywords', type=>'TEXT'}, + { name => 'version', type=>'TEXT'}, + { name => 'notes', type=>'TEXT'}, + { name => 'abstract', type=>'TEXT'}, + { name => 'mime', type=>'TEXT'}, + { name => 'lang', type=>'TEXT'}, + { name => 'owner', type=>'TEXT'}, + { name => 'copyright', type=>'TEXT'}, + { name => 'hostname', type=>'TEXT'}, #-------------------------------------------------- - creationdate =>{ type=>'DATETIME'}, - lastrevisiondate =>{ type=>'DATETIME'}, + { name => 'creationdate', type=>'DATETIME'}, + { name => 'lastrevisiondate', type=>'DATETIME'}, #-------------------------------------------------- ); @@ -1790,9 +1995,8 @@ Returns: the identifier of the table on ###################################################################### sub create_results_table { my $table = &Apache::lonmysql::create_table - ( { columns => \%Datatypes, - column_order => \@DataOrder, - fullindex => \@Fullindicies, + ( { columns => \@Datatypes, + FULLTEXT => [{'columns' => \@Fullindicies},], } ); if (defined($table)) { $ENV{'form.table'} = $table; @@ -1917,7 +2121,7 @@ END if (@Lines > 2) { $pretty_string = join '
',(@Lines[0..2],'....
'); } - $r->print("Search: ".$pretty_string); + $r->print(&mt("Search").": ".$pretty_string); $r->rflush(); # # Determine the servers we need to contact. @@ -1976,25 +2180,33 @@ END my $time_remaining = $max_time - (time - $starttime) ; my $last_time = $time_remaining; &update_seconds($r,$time_remaining); - while (($time_remaining > 0) && + &update_status($r,'contacting '.$Servers_to_contact[0]); + while (($time_remaining > 0) && ((@Servers_to_contact) || keys(%Server_status))) { # Send out a search request if it needs to be done. if (@Servers_to_contact) { # Contact one server my $server = shift(@Servers_to_contact); + &update_status($r,&mt('contacting').' '.$server); my $reply=&Apache::lonnet::metadata_query($query,$customquery, $customshow,[$server]); ($server) = keys(%$reply); $Server_status{$server} = $reply->{$server}; - &update_status($r,'contacting '.$server); } else { # wait a sec. to give time for files to be written # This sleep statement is here instead of outside the else # block because we do not want to pause if we have servers # left to contact. + if (scalar (keys(%Server_status))) { + &update_status($r, + &mt('waiting on').' '.(join(' ',keys(%Server_status)))); + } sleep(1); } - &update_status($r,'waiting on '.(join(' ',keys(%Server_status)))); + # + # + # Loop through the servers we have contacted but do not + # have results from yet, looking for results. while (my ($server,$status) = each(%Server_status)) { last if ($connection->aborted()); if ($status eq 'con_lost') { @@ -2004,12 +2216,12 @@ END $status=~/^([\.\w]+)$/; my $datafile=$r->dir_config('lonDaemons').'/tmp/'.$1; if (-e $datafile && ! -e "$datafile.end") { - &update_status($r,'Receiving results from '.$server); + &update_status($r,&mt('Receiving results from').' '.$server); next; } last if ($connection->aborted()); if (-e "$datafile.end") { - &update_status($r,'Reading results from '.$server); + &update_status($r,&mt('Reading results from').' '.$server); if (-z "$datafile") { delete($Server_status{$server}); next; @@ -2057,13 +2269,14 @@ END } last if ($connection->aborted()); # Finished looping through the servers + $starttime = time if (@Servers_to_contact); $time_remaining = $max_time - (time - $starttime) ; if ($last_time - $time_remaining > 0) { $last_time = $time_remaining; &update_seconds($r,$time_remaining); } } - &update_status($r,'Search Complete'.$server); + &update_status($r,&mt('Search Complete').$server); &update_seconds($r,0); &Apache::lonmysql::disconnect_from_db(); # We have run out of time or run out of servers to talk to and @@ -2207,7 +2420,8 @@ sub display_results { ."\n" ); if ($total_results == 0) { - $r->print("There are currently no results.\n". + $r->print(''. + '

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

'. ""); return; } else { @@ -2224,8 +2438,7 @@ sub display_results { ## foreach my $row (@Results) { if ($connection->aborted()) { - untie %groupsearch_db if (tied(%groupsearch_db)); - &Apache::lonmysql::disconnect_from_db(); + &cleanup(); return; } my %Fields = %{&parse_row(@$row)}; @@ -2239,7 +2452,7 @@ sub display_results { $r->rflush(); } if (@Results < 1) { - $r->print("There were no results matching your query"); + $r->print(&mt("There were no results matching your query")); } else { $r->print ('
'. @@ -2312,7 +2525,7 @@ sub parse_row { my @Row = @_; my %Fields; for (my $i=0;$i<=$#Row;$i++) { - $Fields{$DataOrder[$i]}=&Apache::lonnet::unescape($Row[$i]); + $Fields{$Datatypes[$i]->{'name'}}=&Apache::lonnet::unescape($Row[$i]); } $Fields{'language'} = &Apache::loncommon::languagedescription($Fields{'lang'}); @@ -2482,8 +2695,16 @@ Checked for existance & 'edit' mode. =item 'form.form' +Contains the name of the form that has the input fields to set + =item 'form.element' +the name of the input field to put the URL into + +=item 'form.titleelement' + +the name of the input field to put the title into + =back =cut @@ -2520,14 +2741,31 @@ SCRIPT } elsif ($ENV{'form.mode'} eq 'edit') { my $form = $ENV{'form.form'}; my $element = $ENV{'form.element'}; + my $titleelement = $ENV{'form.titleelement'}; + my $changetitle; + if (!$titleelement) { + $changetitle='function changeTitle(val) {}'; + } else { + $changetitle=< function select_data(title,url) { changeURL(url); + changeTitle(title); parent.close(); } -function changeTitle(val) { -} +$changetitle function changeURL(val) { if (parent.targetwin.document) { parent.targetwin.document.forms["$form"].elements["$element"].value=val; @@ -2543,10 +2781,19 @@ SCRIPT $result.=<