--- loncom/interface/lonsearchcat.pm 2004/05/05 14:14:10 1.222
+++ loncom/interface/lonsearchcat.pm 2005/02/02 22:03:27 1.230.2.3
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Search Catalog
#
-# $Id: lonsearchcat.pm,v 1.222 2004/05/05 14:14:10 matthew Exp $
+# $Id: lonsearchcat.pm,v 1.230.2.3 2005/02/02 22:03:27 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -75,6 +75,7 @@ use Apache::lonhtmlcommon;
use Apache::lonlocal;
use LONCAPA::lonmetadata();
use HTML::Entities();
+use Parse::RecDescent;
######################################################################
######################################################################
@@ -174,6 +175,7 @@ sub handler {
'&launch='.$ENV{'form.launch'}.
'&mode='.$ENV{'form.mode'},
text=>"Course and Catalog Search",
+ target=>'_top',
bug=>'Searching',});
} else {
&Apache::lonhtmlcommon::add_breadcrumb
@@ -182,6 +184,7 @@ sub handler {
'&launch='.$ENV{'form.launch'}.
'&mode='.$ENV{'form.mode'},
text=>"Catalog Search",
+ target=>'_top',
bug=>'Searching',});
}
#
@@ -231,24 +234,19 @@ END
$hidden_fields = ''."\n";
if (exists($ENV{'form.catalogmode'})) {
- $hidden_fields .= ''."\n";
+ $hidden_fields .= &hidden_field('catalogmode');
}
if (exists($ENV{'form.form'})) {
- $hidden_fields .= ''."\n";
+ $hidden_fields .= &hidden_field('form');
}
if (exists($ENV{'form.element'})) {
- $hidden_fields .= ''."\n";
+ $hidden_fields .= &hidden_field('element');
}
if (exists($ENV{'form.titleelement'})) {
- $hidden_fields .= ''."\n";
+ $hidden_fields .= &hidden_field('titleelement');
}
if (exists($ENV{'form.mode'})) {
- $hidden_fields .= ''."\n";
+ $hidden_fields .= &hidden_field('mode');
}
##
## Configure dynamic components of interface
@@ -340,6 +338,29 @@ END
&course_search($r);
} elsif(($ENV{'form.phase'} eq 'basic_search') ||
($ENV{'form.phase'} eq 'adv_search')) {
+ #
+ # We are running a search, try to parse it
+ my ($query,$customquery,$customshow,$libraries) =
+ (undef,undef,undef,undef);
+ my $pretty_string;
+ if ($ENV{'form.phase'} eq 'basic_search') {
+ ($query,$pretty_string,$libraries) =
+ &parse_basic_search($r,$closebutton,$hidden_fields);
+ return OK if (! defined($query));
+ &make_persistent({ basicexp => $ENV{'form.basicexp'}},
+ $persistent_db_file);
+ } else { # Advanced search
+ ($query,$customquery,$customshow,$libraries,$pretty_string)
+ = &parse_advanced_search($r,$closebutton,$hidden_fields);
+ return OK if (! defined($query));
+ }
+ &make_persistent({ query => $query,
+ customquery => $customquery,
+ customshow => $customshow,
+ libraries => $libraries,
+ pretty_string => $pretty_string },
+ $persistent_db_file);
+ #
# Set up table
if (! defined(&create_results_table())) {
my $errorstring=&Apache::lonmysql::get_error();
@@ -367,29 +388,12 @@ Unable to properly store search informat
END
return OK;
}
- #
- # We are running a search
- my ($query,$customquery,$customshow,$libraries) =
- (undef,undef,undef,undef);
- my $pretty_string;
- if ($ENV{'form.phase'} eq 'basic_search') {
- ($query,$pretty_string,$libraries) =
- &parse_basic_search($r,$closebutton,$hidden_fields);
- } else { # Advanced search
- ($query,$customquery,$customshow,$libraries,$pretty_string)
- = &parse_advanced_search($r,$closebutton,$hidden_fields);
- return OK if (! defined($query));
- }
- &make_persistent({ query => $query,
- customquery => $customquery,
- customshow => $customshow,
- libraries => $libraries,
- pretty_string => $pretty_string },
- $persistent_db_file);
##
## Print out the frames interface
##
- &print_frames_interface($r);
+ if (defined($query)) {
+ &print_frames_interface($r);
+ }
}
return OK;
}
@@ -422,6 +426,14 @@ sub clean_up_environment {
}
}
+sub hidden_field {
+ my ($name,$value) = @_;
+ if (! defined($value)) {
+ $value = $ENV{'form.'.$name};
+ }
+ return ''.$/;
+}
+
######################################################################
######################################################################
##
@@ -436,12 +448,22 @@ my %alreadyseen;
my %hash;
my $totalfound;
+sub make_symb {
+ my ($id)=@_;
+ my ($mapid,$resid)=split(/\./,$id);
+ my $map=$hash{'map_id_'.$mapid};
+ my $res=$hash{'src_'.$id};
+ my $symb=&Apache::lonnet::encode_symb($map,$resid,$res);
+ return $symb;
+}
+
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;
+ undef(%alreadyseen);
if ($ENV{'form.crsrelated'}) {
($search_string,@New_Words) = &related_version($ENV{'form.courseexp'});
if (@New_Words) {
@@ -457,16 +479,18 @@ sub course_search {
$bodytag.'
'.$pretty_search_string.'
');
$r->rflush();
# ======================================================= Go through the course
- undef %alreadyseen;
- %alreadyseen=();
my $c=$r->connection;
if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.".db",
&GDBM_READER(),0640)) {
- foreach (keys %hash) {
+ foreach (sort(keys(%hash))) {
if ($c->aborted()) { last; }
- if (($_=~/^src\_(.+)$/) && (!$alreadyseen{$hash{$_}})) {
- &checkonthis($r,$hash{$_},0,$hash{'title_'.$1},$fulltext,
- @allwords);
+ 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);
@@ -481,15 +505,22 @@ sub course_search {
# =============================== This pulls up a resource and its dependencies
sub checkonthis {
- my ($r,$url,$level,$title,$fulltext,@allwords)=@_;
- $alreadyseen{$url}=1;
+ my ($r,$id,$url,$level,$title,$fulltext,$symb,@allwords)=@_;
+ $alreadyseen{$id}=1;
+ if (&Apache::loncommon::connection_aborted($r)) { return; }
$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);
+
+ 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='.&Apache::lonnet::escape($symb));
}
$result=~s/\s+/ /gs;
my $applies=0;
@@ -506,8 +537,15 @@ sub checkonthis {
for (my $i=0;$i<=$level*5;$i++) {
$r->print(' ');
}
- $r->print(''.
- ($title?$title:$url).'
');
+ my $href=$url;
+ if ($hash{'encrypted_'.$id} && !$ENV{'request.role.adv'}) {
+ $href=&Apache::lonenc::encrypted($href)
+ .'?symb='.&Apache::lonenc::encrypted($symb);
+ } else {
+ $href.='?symb='.&Apache::lonnet::escape($symb);
+ }
+ $r->print(''.($title?$title:$url).
+ '
');
$totalfound++;
} elsif ($fulltext) {
$r->print(' .');
@@ -517,8 +555,8 @@ sub checkonthis {
my $dependencies=
&Apache::lonnet::metadata($url,'dependencies');
foreach (split(/\,/,$dependencies)) {
- if (($_=~/^\/res\//) && (!$alreadyseen{$_})) {
- &checkonthis($r,$_,$level+1,'',$fulltext,@allwords);
+ if (($_=~/^\/res\//) && (!$alreadyseen{$id})) {
+ &checkonthis($r,$id,$_,$level+1,'',$fulltext,undef,@allwords);
}
}
}
@@ -556,9 +594,11 @@ Prints the form for the basic search. S
######################################################################
sub print_basic_search_form {
my ($r,$closebutton,$hidden_fields) = @_;
+ my $result = ($ENV{'form.catalogmode'} ne 'groupsearch');
my $bodytag=&Apache::loncommon::bodytag('Search').
- &Apache::lonhtmlcommon::breadcrumbs(undef,'Searching','Searching',
- undef,undef,! $ENV{'form.launch'});
+ &Apache::lonhtmlcommon::breadcrumbs(undef,'Searching','Search_Basic',
+ undef,undef,
+ $ENV{'form.catalogmode'} ne 'groupsearch');
my $scrout = &search_html_header().$bodytag;
if (&Apache::lonnet::allowed('bre',$ENV{'request.role.domain'})) {
# Define interface components
@@ -596,8 +636,11 @@ sub print_basic_search_form {
}
$scrout.=''.$/.''.'';
@@ -686,10 +724,9 @@ sub print_advanced_search_form{
my ($r,$closebutton,$hidden_fields) = @_;
my $bodytag=&Apache::loncommon::bodytag('Advanced Catalog Search').
&Apache::lonhtmlcommon::breadcrumbs(undef,'Searching',
- 'Searching',
+ 'Search_Advanced',
undef,undef,
- ! $ENV{'form.launch'});
-
+ $ENV{'form.catalogmode'} ne 'groupsearch');
my %lt=&Apache::lonlocal::texthash('srch' => 'Search',
'reset' => 'Reset',
'help' => 'Help');
@@ -770,7 +807,7 @@ ENDHEADER
$scrout.=''.
&titlefield(&mt('Copyright/Distribution')).' | '.
&Apache::lonmeta::selectbox('copyright',
- '',,
+ $ENV{'form.copyright'},
\&Apache::loncommon::copyrightdescription,
( undef,
&Apache::loncommon::copyrightids)
@@ -778,7 +815,7 @@ ENDHEADER
$scrout.=' |
'.
&titlefield(&mt('Language')).' | '.
&Apache::lonmeta::selectbox('language',
- 'notset',,
+ $ENV{'form.language'},
\&Apache::loncommon::languagedescription,
('any',&Apache::loncommon::languageids)
).' |
';
@@ -959,7 +996,7 @@ Outputs: text for box with view options
######################################################################
######################################################################
sub viewoptions {
- my $scrout="\n".'';
+ my $scrout;
if (! defined($ENV{'form.viewselect'})) {
$ENV{'form.viewselect'}='detailed';
}
@@ -993,7 +1030,7 @@ Outputs: return little blurb on how to e
######################################################################
######################################################################
sub searchhelp {
- return &mt('Enter terms or phrases separated by AND, OR, or NOT');
+ return &mt('Enter words and quoted phrases');
}
######################################################################
@@ -1184,13 +1221,13 @@ Parse advanced search form and return th
sub parse_advanced_search {
my ($r,$closebutton,$hidden_fields)=@_;
my @BasicFields = ('title','author','subject','keywords','url','version',
- 'notes','abstract','extension','owner',
+ 'notes','abstract','extension','owner','authorspace',
# 'custommetadata','customshow',
'modifyinguser','standards','mime');
my @StatsFields = &statfields();
my @EvalFields = &evalfields();
my $fillflag=0;
- my $pretty_search_string = "
\n";
+ my $pretty_search_string = "";
# Clean up fields for safety
for my $field (@BasicFields,
'creationdatestart_month','creationdatestart_day',
@@ -1200,7 +1237,6 @@ sub parse_advanced_search {
'lastrevisiondatestart_year','lastrevisiondateend_month',
'lastrevisiondateend_day','lastrevisiondateend_year') {
$ENV{'form.'.$field}=~s/[^\w\/\s\(\)\=\-\"\']//g;
- $ENV{'form.'.$field}=~s/(not\s*$|^\s*(and|or)|)//gi;
}
foreach ('mode','form','element') {
# is this required? Hmmm.
@@ -1244,22 +1280,30 @@ sub parse_advanced_search {
my $font = '';
# Evaluate logical expression AND/OR/NOT phrase fields.
foreach my $field (@BasicFields) {
- if ($ENV{'form.'.$field}) {
- my $searchphrase = $ENV{'form.'.$field};
- $pretty_search_string .= $font."$field contains ".
- $searchphrase."";
+ next if (!defined($ENV{'form.'.$field}) || $ENV{'form.'.$field} eq '');
+ my ($error,$SQLQuery) =
+ &process_phrase_input($ENV{'form.'.$field},
+ $ENV{'form.'.$field.'_related'},$field);
+ if (defined($error)) {
+ &output_unparsed_phrase_error($r,$closebutton,'phase=disp_adv',
+ $hidden_fields,$field);
+ return;
+ } else {
+ $pretty_search_string .=
+ $font.$field.': '.$ENV{'form.'.$field};
if ($ENV{'form.'.$field.'_related'}) {
- my @New_Words;
- ($searchphrase,@New_Words) = &related_version($searchphrase);
- if (@New_Words) {
- $pretty_search_string .= " with related words: ".
- "@New_Words.";
+ my @Words =
+ &Apache::loncommon::get_related_words
+ ($ENV{'form.'.$field});
+ if (@Words) {
+ $pretty_search_string.= ' with related words: '.
+ join(', ',@Words[0..4]);
} else {
- $pretty_search_string .= " with no related words.";
+ $pretty_search_string.= ' with related words.';
}
}
- $pretty_search_string .= "
\n";
- push @queries,&build_SQL_query($field,$searchphrase);
+ $pretty_search_string .= '
';
+ push (@queries,$SQLQuery);
}
}
#
@@ -1276,7 +1320,8 @@ sub parse_advanced_search {
}
}
if (defined($searchphrase)) {
- push @queries,&build_SQL_query('mime',$searchphrase);
+ my ($error,$SQLsearch) = &process_phrase_input($searchphrase,0,'mime');
+ push @queries,$SQLsearch;
$pretty_search_string .=$font.'mime contains '.
$searchphrase.'
';
}
@@ -1308,7 +1353,7 @@ sub parse_advanced_search {
push @queries,"(copyright like \"$ENV{'form.copyright'}\")";
$pretty_search_string.=$font."copyright = ".
&Apache::loncommon::copyrightdescription($ENV{'form.copyright'}).
- "
\n";
+ "
\n";
}
#
# Statistics
@@ -1396,11 +1441,11 @@ sub parse_advanced_search {
$pretty_search_string .= $pretty_domains_string."
\n";
#
if (@queries) {
- $query="select * from metadata where ".join(" AND ",@queries);
+ $query="SELECT * FROM metadata WHERE (".join(") AND (",@queries).')';
} elsif ($customquery) {
$query = '';
}
-# &Apache::lonnet::logthis('query = '.$/.$query);
+ # &Apache::lonnet::logthis('query = '.$/.$query);
return ($query,$customquery,$customshow,$libraries_to_query,
$pretty_search_string);
}
@@ -1462,7 +1507,7 @@ sub parse_basic_search {
#
# Clean up fields for safety
for my $field ('basicexp') {
- $ENV{"form.$field"}=~s/[^\w\s\(\)\-]//g;
+ $ENV{"form.$field"}=~s/[^\w\s\'\"\!\(\)\-]//g;
}
foreach ('mode','form','element') {
# is this required? Hmmm.
@@ -1475,39 +1520,220 @@ sub parse_basic_search {
#
# Check to see if enough of a query is filled in
my $search_string = $ENV{'form.basicexp'};
- $search_string =~ s/(not\s*$|^\s*(and|or)|)//gi;
if (! &filled($search_string)) {
&output_blank_field_error($r,$closebutton,'phase=disp_basic');
return OK;
}
- my $pretty_search_string = ''.$ENV{'form.basicexp'}.'';
- if ($ENV{'form.related'}) {
- my @New_Words;
- ($search_string,@New_Words) = &related_version($ENV{'form.basicexp'});
- if (@New_Words) {
- $pretty_search_string .= " with related words: @New_Words.";
- } else {
- $pretty_search_string .= " with no related words.";
- }
+ my $pretty_search_string=$search_string;
+ my @Queries;
+ my $searchfield = 'concat_ws(" ",'.join(',',
+ ('title','author','subject',
+ 'notes','abstract','keywords')
+ ).')';
+ my ($error,$SQLQuery) = &process_phrase_input($search_string,
+ $ENV{'form.related'},
+ $searchfield);
+ if ($error) {
+ &output_unparsed_phrase_error($r,$closebutton,'phase=disp_basic',
+ '','basicexp');
+ return;
}
+ push(@Queries,$SQLQuery);
+ #foreach my $q (@Queries) {
+ # &Apache::lonnet::logthis(' '.$q);
+ #}
+ my $final_query = 'SELECT * FROM metadata WHERE '.join(" AND ",@Queries);
#
- # Build SQL query string based on form page
- my $query='';
- my $concatarg=join(',',
- ('title', 'author', 'subject', 'notes', 'abstract',
- 'keywords'));
- $concatarg='title' if $ENV{'form.titleonly'};
- $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";
- my $final_query = 'SELECT * FROM metadata WHERE '.$query;
+ $pretty_search_string =~ s:^
and ::;
# &Apache::lonnet::logthis($final_query);
return ($final_query,$pretty_search_string,
$libraries_to_query);
}
+
+###############################################################
+###############################################################
+
+my @Phrases;
+
+sub concat {
+ my ($item) = @_;
+ my $results = '';
+ foreach (@$item) {
+ if (ref($_) eq 'ARRAY') {
+ $results .= join(' ',@$_);
+ }
+ }
+ return $results;
+}
+
+sub process_phrase_input {
+ my ($phrase,$related,$field)=@_;
+ #&Apache::lonnet::logthis('phrase = :'.$phrase.':');
+ my $grammar = <<'ENDGRAMMAR';
+ searchphrase:
+ expression /^\Z/ {
+ # &Apache::lonsearchcat::print_item(\@item,0);
+ [@item];
+ }
+ expression:
+ phrase(s) {
+ [@item];
+ }
+ phrase:
+ orword {
+ [@item];
+ }
+ | andword {
+ [@item];
+ }
+ | minusword {
+ unshift(@::Phrases,$item[1]->[0]);
+ unshift(@::Phrases,$item[1]->[1]);
+ [@item];
+ }
+ | word {
+ unshift(@::Phrases,$item[1]);
+ [@item];
+ }
+ #
+ orword:
+ word 'OR' phrase {
+ unshift(@::Phrases,'OR');
+ unshift(@::Phrases,$item[1]);
+ [@item];
+ }
+ | word 'or' phrase {
+ unshift(@::Phrases,'OR');
+ unshift(@::Phrases,$item[1]);
+ [@item];
+ }
+ | minusword 'OR' phrase {
+ unshift(@::Phrases,'OR');
+ unshift(@::Phrases,$item[1]->[0]);
+ unshift(@::Phrases,$item[1]->[1]);
+ [@item];
+ }
+ | minusword 'or' phrase {
+ unshift(@::Phrases,'OR');
+ unshift(@::Phrases,$item[1]->[0]);
+ unshift(@::Phrases,$item[1]->[1]);
+ [@item];
+ }
+ andword:
+ word phrase {
+ unshift(@::Phrases,'AND');
+ unshift(@::Phrases,$item[1]);
+ [@item];
+ }
+ | minusword phrase {
+ unshift(@::Phrases,'AND');
+ unshift(@::Phrases,$item[1]->[0]);
+ unshift(@::Phrases,$item[1]->[1]);
+ [@item];
+ }
+ #
+ minusword:
+ '-' word {
+ [$item[2],'NOT'];
+ }
+ word:
+ "'" term(s) "'" {
+ &Apache::lonsearchcat::concat(\@item);
+ }
+ | '"' term(s) '"' {
+ &Apache::lonsearchcat::concat(\@item);
+ }
+ | term {
+ $item[1];
+ }
+ term:
+ /[\w\Q:!@#$%^&*()+_=|{}<>,.;\\\/?\E]+/ {
+ $item[1];
+ }
+ENDGRAMMAR
+ #
+ # The end result of parsing the phrase with the grammar is an array
+ # @::Phrases.
+ # $phrase = "gene splicing" or cat -> "gene splicing","OR","cat"
+ # $phrase = "genetic engineering" -dna ->
+ # "genetic engineering","AND","NOT","dna"
+ # $phrase = cat or dog -poodle -> "cat","OR","dog","AND","NOT","poodle"
+ undef(@::Phrases);
+ my $p = new Parse::RecDescent($grammar);
+ if (! defined($p->searchphrase($phrase))) {
+ &Apache::lonnet::logthis('lonsearchcat:unable to process:'.$phrase);
+ return 'Unable to process phrase '.$phrase;
+ }
+ #
+ # Go through the phrases and make sense of them.
+ # Apply modifiers NOT OR and AND to the phrases.
+ my @NewPhrases;
+ while(@::Phrases) {
+ my $phrase = shift(@::Phrases);
+ # &Apache::lonnet::logthis('phrase = '.$phrase);
+ my $phrasedata;
+ if ($phrase =~ /^(NOT|OR|AND)$/) {
+ if ($phrase eq 'OR') {
+ $phrasedata->{'or'}++;
+ if (! @::Phrases) { $phrasedata = undef; last; }
+ $phrase = shift(@::Phrases);
+ } elsif ($phrase eq 'AND') {
+ $phrasedata->{'and'}++;
+ if (! @::Phrases) { $phrasedata = undef; last; }
+ $phrase = shift(@::Phrases);
+ }
+ if ($phrase eq 'NOT') {
+ $phrasedata->{'negate'}++;
+ if (! @::Phrases) { $phrasedata = undef; last; }
+ $phrase = shift(@::Phrases);
+ }
+ }
+ $phrasedata->{'phrase'} = $phrase;
+ if ($related) {
+ my @NewWords;
+ (undef,@NewWords) = &related_version($phrasedata->{'phrase'});
+ $phrasedata->{'related_words'} = \@NewWords;
+ }
+ push(@NewPhrases,$phrasedata);
+ }
+ #
+ # Actually build the sql query from the phrases
+ my $SQLQuery;
+ foreach my $phrase (@NewPhrases) {
+ my $query;
+ if ($phrase->{'negate'}) {
+ $query .= $field.' NOT LIKE "%'.$phrase->{'phrase'}.'%"';
+ } else {
+ $query .= $field.' LIKE "%'.$phrase->{'phrase'}.'%"';
+ }
+ foreach my $related (@{$phrase->{'related_words'}}) {
+ if ($phrase->{'negate'}) {
+ $query .= ' AND '.$field.' NOT LIKE "%'.$related.'%"';
+ } else {
+ $query .= ' OR '.$field.' LIKE "%'.$related.'%"';
+ }
+ }
+ if ($SQLQuery) {
+ if ($phrase->{'or'}) {
+ $SQLQuery .= ' OR ('.$query.')';
+ } else {
+ $SQLQuery .= ' AND ('.$query.')';
+ }
+ } else {
+ $SQLQuery = '('.$query.')';
+ }
+ }
+ #
+ # &Apache::lonnet::logthis("SQLQuery = $SQLQuery");
+ #
+ return undef,$SQLQuery;
+}
+
######################################################################
######################################################################
@@ -1526,45 +1752,15 @@ Note: Using this twice on a string is pr
######################################################################
######################################################################
sub related_version {
- my $search_string = shift;
- my $result = $search_string;
- my %New_Words = ();
- while ($search_string =~ /(\w+)/cg) {
- my $word = $1;
- next if (lc($word) =~ /\b(or|and|not)\b/);
- my @Words = &Apache::loncommon::get_related_words($word);
- @Words = ($#Words>4? @Words[0..4] : @Words);
- foreach (@Words) { $New_Words{$_}++;}
- my $replacement = join " OR ", ($word,@Words);
- $result =~ s/(\b)$word(\b)/$1($replacement)$2/g;
- }
- return $result,sort(keys(%New_Words));
+ my ($word) = @_;
+ return (undef) if (lc($word) =~ /\b(or|and|not)\b/);
+ my @Words = &Apache::loncommon::get_related_words($word);
+ # Only use 4 related words
+ @Words = ($#Words>4? @Words[0..4] : @Words);
+ my $result = join " OR ", ($word,@Words);
+ return $result,sort(@Words);
}
-######################################################################
-######################################################################
-
-=pod
-
-=item &build_SQL_query()
-
-Builds a SQL query string from a logical expression with AND/OR keywords
-using Text::Query and &recursive_SQL_query_builder()
-
-=cut
-
-######################################################################
-######################################################################
-sub build_SQL_query {
- my ($field_name,$logic_statement)=@_;
- my $q=new Text::Query('abc',
- -parse => 'Text::Query::ParseAdvanced',
- -build => 'Text::Query::Build');
- $q->prepare($logic_statement);
- my $matchexp=${$q}{'matchexp'}; chomp $matchexp;
- my $sql_query=&recursive_SQL_query_build($field_name,$matchexp);
- return $sql_query;
-}
######################################################################
######################################################################
@@ -1599,47 +1795,6 @@ sub build_custommetadata_query {
return $matchexp;
}
-######################################################################
-######################################################################
-
-=pod
-
-=item &recursive_SQL_query_build()
-
-Recursively constructs an SQL query. Takes as input $dkey and $pattern.
-
-=cut
-
-######################################################################
-######################################################################
-sub recursive_SQL_query_build {
- my ($dkey,$pattern)=@_;
- 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 (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);
- }
- &recursive_SQL_query_build($dkey,$pattern);
-}
######################################################################
######################################################################
@@ -1832,7 +1987,11 @@ a link to change the search query.
######################################################################
sub print_sort_form {
my ($r,$pretty_query_string) = @_;
- my $bodytag=&Apache::loncommon::bodytag(undef,undef,undef,1);
+ my $bodytag=&Apache::loncommon::bodytag(undef,undef,undef,1).
+ &Apache::lonhtmlcommon::breadcrumbs
+ (undef,'Searching','Searching',undef,undef,
+ $ENV{'form.catalogmode'} ne 'groupsearch');
+
##
my %SortableFields=&Apache::lonlocal::texthash(
id => 'Default',
@@ -2098,6 +2257,9 @@ results into MySQL.
sub run_search {
my ($r,$query,$customquery,$customshow,$serverlist,$pretty_string) = @_;
my $bodytag=&Apache::loncommon::bodytag(undef,undef,undef,1);
+ $bodytag.=&Apache::lonhtmlcommon::breadcrumbs
+ (undef,'Searching','Searching',undef,undef,
+ $ENV{'form.catalogmode'} ne 'groupsearch');
my $connection = $r->connection;
#
# Print run_search header
@@ -2109,12 +2271,16 @@ $bodytag