From 84d2dc0bb73091d923e99c3a4b77618c6c6b719e Mon Sep 17 00:00:00 2001 From: JT Smith Date: Sat, 1 Jun 2002 06:28:31 +0000 Subject: [PATCH] Adding search engine to Message Board and USS. --- lib/WebGUI/DateTime.pm | 2 +- lib/WebGUI/Discussion.pm | 158 +++++++++++++++------ lib/WebGUI/Paginator.pm | 2 +- lib/WebGUI/Search.pm | 202 +++++++++++++++++++++++++++ lib/WebGUI/Wobject/MessageBoard.pm | 9 +- lib/WebGUI/Wobject/UserSubmission.pm | 65 ++++++++- 6 files changed, 391 insertions(+), 47 deletions(-) create mode 100644 lib/WebGUI/Search.pm diff --git a/lib/WebGUI/DateTime.pm b/lib/WebGUI/DateTime.pm index f3cb0434a..a9fb8967b 100644 --- a/lib/WebGUI/DateTime.pm +++ b/lib/WebGUI/DateTime.pm @@ -101,7 +101,7 @@ sub epochToHuman { $date[4]++; # offset the months starting from 0 $date[5] += 1900; # original value is Year-1900 $date[6]++; # offset for weekdays starting from 0 - $output = $_[1]; + $output = $_[1] || "%z %Z"; #---dealing with percent symbol $output =~ s/\%\%/\%/g; #---date format preference diff --git a/lib/WebGUI/Discussion.pm b/lib/WebGUI/Discussion.pm index 84d04dfd8..1d5bb6aa6 100644 --- a/lib/WebGUI/Discussion.pm +++ b/lib/WebGUI/Discussion.pm @@ -16,6 +16,8 @@ use WebGUI::DateTime; use WebGUI::HTML; use WebGUI::HTMLForm; use WebGUI::International; +use WebGUI::Paginator; +use WebGUI::Search; use WebGUI::Session; use WebGUI::SQL; use WebGUI::URL; @@ -86,8 +88,12 @@ sub deleteMessageConfirm { #------------------------------------------------------------------- sub formatHeader { - my $output; - $output = ''.WebGUI::International::get(237).' '.formatSubject($_[0]).'
' if ($_[0] ne ""); + my ($output, $subject); + $subject = formatSubject($_[0]); + if ($_[5] ne "") { + $subject = ''.$subject.''; + } + $output = ''.WebGUI::International::get(237).' '.$subject.'
' if ($_[0] ne ""); $output .= ''.WebGUI::International::get(238).' '.$_[2].'
' if ($_[1] && $_[2] ne ""); $output .= "".WebGUI::International::get(239)." ".epochToHuman($_[3],"%z %Z")."
" if ($_[3]); @@ -209,6 +215,45 @@ sub purge { WebGUI::SQL->write("delete from discussion where wobjectId=$_[0]"); } +#------------------------------------------------------------------- +sub search { + my ($p, $i, $output, $constraints, $sql, $sth, %data, @row, $url); + $output = WebGUI::Search::form({wid=>"$session{form}{wid}",sid=>"$session{form}{sid}",func=>'search'}); + $constraints = WebGUI::Search::buildConstraints([qw(username subject message)]); + if ($constraints ne "") { + tie %data, 'Tie::CPHash'; + $url = WebGUI::URL::page('func=search&wid='.$session{form}{wid}.'&sid='.$session{form}{sid} + .'&all='.WebGUI::URL::escape($session{form}{all}) + .'&exactPhrase='.WebGUI::URL::escape($session{form}{exactPhrase}).'&atLeastOne=' + .WebGUI::URL::escape($session{form}{atLeastOne}).'&numResults='.$session{form}{numResults} + .'&without='.WebGUI::URL::escape($session{form}{without})); + $output .= ''; + $output .= ''; + $sql = "select * from discussion where wobjectId=$session{form}{wid} "; + $sql .= " and subId=$session{form}{sid} " if ($session{form}{sid}); + $sql .= " and ".$constraints." order by dateOfPost desc"; + $sth = WebGUI::SQL->read($sql); + while (%data = $sth->hash) { + $data{subject} = substr(WebGUI::HTML::filter($data{subject},'all'),0,30); + $row[$i] .= ''; + $i++; + } + $sth->finish; + $p = WebGUI::Paginator->new($url,\@row,$session{form}{numResults}); + $output .= $p->getPage($session{form}{pn}); + $output .= '
'.WebGUI::International::get(229). + ''.WebGUI::International::get(244). + ''.WebGUI::International::get(245).'
'.$data{subject}. + ''.$data{username}. + ''.epochToHuman($data{dateOfPost}). + '
'; + $output .= $p->getBarTraditional($session{form}{pn}); + } + return $output; +} + #------------------------------------------------------------------- sub showMessage { my (@data, $html, %message, $sqlAdd); @@ -227,7 +272,6 @@ sub showMessage { $html .= formatHeader($message{subject},$message{userId},$message{username},$message{dateOfPost},$message{views}); $html .= ''; $html .= ''; - $html .= $_[0]; @data = WebGUI::SQL->quickArray("select max(messageId) from discussion where wobjectId=$message{wobjectId} and pid=0 and messageId<$message{rid}".$sqlAdd); if ($data[0] ne "") { @@ -240,6 +284,7 @@ sub showMessage { $html .= ''.WebGUI::International::get(512).' »
'; } + $html .= $_[0]; $html .= ''; $html .= formatMessage($message{message}).'

'; $html .= ''; @@ -251,26 +296,48 @@ sub showMessage { #------------------------------------------------------------------- sub showReplyTree { - my (@data, $html, %message, @data); + my (@data, $html, $sql, %message, $sth, %data); tie %message, 'Tie::CPHash'; + tie %data, 'Tie::CPHash'; %message = getMessage($session{form}{mid}); if ($message{messageId}) { $html .= ''; - $html .= ''; - @data = WebGUI::SQL->quickArray("select messageId,subject,username,dateOfPost,userId from discussion where messageId=$message{rid}"); - $data[1] = WebGUI::HTML::filter($data[1],'all'); - $html .= ''.substr($data[1],0,30).''; - $html .= traverseReplyTree($message{rid},0); + if ($session{user}{discussionLayout} eq "threaded") { + $html .= ''; + @data = WebGUI::SQL->quickArray("select messageId,subject,username,dateOfPost,userId + from discussion where messageId=$message{rid}"); + $data[1] = WebGUI::HTML::filter($data[1],'all'); + $html .= ''.substr($data[1],0,30).''; + $html .= traverseReplyTree($message{rid},0); + } else { + $sql = "select * from discussion where rid=$message{rid} and wobjectId=$session{form}{wid}"; + if ($session{form}{sid}) { + $sql .= " and subId=$session{form}{sid}"; + } + $sql .= " order by messageId"; + $sth = WebGUI::SQL->read($sql); + while (%data = $sth->hash) { + $html .= ''; + } + $sth->finish; + } $html .= "
'.WebGUI::International::get(229). - ''.WebGUI::International::get(244). - ''.WebGUI::International::get(245).'
'.$data[2]. - ''. - epochToHuman($data[3],"%z %Z").'
'.WebGUI::International::get(229). + ''.WebGUI::International::get(244). + ''.WebGUI::International::get(245).'
'.$data[2]. + ''. + epochToHuman($data[3],"%z %Z").'
'; + $html .= formatHeader($data{subject},$data{userId},$data{username},$data{dateOfPost},$data{views}, + WebGUI::URL::page('func=showMessage&mid='.$data{messageId}.'&wid='.$session{form}{wid})); + $html .= '

"; } return $html; @@ -283,36 +350,41 @@ sub showThreads { if ($session{form}{sid}) { $sql .= " and subId=$session{form}{sid}"; } - $sql .= " and pid=0 order by messageId desc"; - $sth = WebGUI::SQL->read($sql); + $sql .= " and pid=0"; $html .= ''; - if ($session{user}{discussionLayout} eq "flat") { - while (%data = $sth->hash) { - $html .= ''; - $html .= ''; - } - } else { - $html .= '
'; - $html .= formatHeader($data{subject},$data{userId},$data{username},$data{dateOfPost},$data{views}); - $html .= '
'.formatMessage($data{message}).'
'; - $html .= ' - - '; - while (%data = $sth->hash) { - $data{subject} = WebGUI::HTML::filter($data{subject},'all'); - $html .= 'read($sql); + $html .= ' + + ' if ($sth->rows); + while (%data = $sth->hash) { + $data{subject} = WebGUI::HTML::filter($data{subject},'all'); + $html .= ''.substr($data{subject},0,30). ''; - $html .= WebGUI::Discussion::traverseReplyTree($data{messageId},1); - } - $html .= '
'.WebGUI::International::get(229).''.WebGUI::International::get(244).''.WebGUI::International::get(245).'
'.WebGUI::International::get(229).''.WebGUI::International::get(244).''.WebGUI::International::get(245).'
'.$data{username}. ''.epochToHuman($data{dateOfPost},"%z %Z"). '
'; + $html .= WebGUI::Discussion::traverseReplyTree($data{messageId},1); + } + } else { + $sql .= " order by dateOfPost"; + $sth = WebGUI::SQL->read($sql); + while (%data = $sth->hash) { + $html .= ''; + $html .= formatHeader($data{subject},$data{userId},$data{username},$data{dateOfPost},$data{views}, + WebGUI::URL::page('func=showMessage&mid='.$data{messageId}.'&wid='.$session{form}{wid})); + $html .= '
'; + } } $html .= ''; $sth->finish; diff --git a/lib/WebGUI/Paginator.pm b/lib/WebGUI/Paginator.pm index a6f224777..fb5ac57d1 100644 --- a/lib/WebGUI/Paginator.pm +++ b/lib/WebGUI/Paginator.pm @@ -395,7 +395,7 @@ sub new { $class = shift; $currentURL = shift; $rowRef = shift; - $rowsPerPage = shift || 50; + $rowsPerPage = shift || 25; $formVar = shift || "pn"; $pageRef = _generatePages($rowRef,$rowsPerPage); bless {_url => $currentURL, _rpp => $rowsPerPage, _rowRef => $rowRef, diff --git a/lib/WebGUI/Search.pm b/lib/WebGUI/Search.pm new file mode 100644 index 000000000..f0d352f07 --- /dev/null +++ b/lib/WebGUI/Search.pm @@ -0,0 +1,202 @@ +package WebGUI::Search; + +=head1 LEGAL + + ------------------------------------------------------------------- + WebGUI is Copyright 2001-2002 Plain Black Software. + ------------------------------------------------------------------- + Please read the legal notices (docs/legal.txt) and the license + (docs/license.txt) that came with this distribution before using + this software. + ------------------------------------------------------------------- + http://www.plainblack.com info@plainblack.com + ------------------------------------------------------------------- + +=cut + + +use strict; +use Tie::IxHash; +use WebGUI::HTMLForm; +use WebGUI::International; +use WebGUI::Session; +use WebGUI::SQL; + + +=head1 NAME + + Package WebGUI::Search + +=head1 SYNOPSIS + + use WebGUI::Search; + $html = WebGUI::Search::form(\%hidden); + $sql = WebGUI::buildConstraints(\@fields); + +=head1 DESCRIPTION + + A package built to take the hassle out of creating advanced search + functionality in WebGUI applications. + +=head1 METHODS + + These methods are available from this package: + +=cut + + +#------------------------------------------------------------------- + +=head2 form ( hiddenFields ) { [ numResults ] } + + Generates and returns the advanced search form. + +=item hiddenFields + + A hash reference that contains any name/value pairs that should be + included as hidden fields in the search form. + +=item numResults + + A form param that can optionally specify the number of results to + display. Defaults to 25. + +=cut + +sub form { + my ($key, $numResults, $output, $f, $resultsText, %results); + tie %results, 'Tie::IxHash'; + $numResults = $session{form}{numResults} || 25; + $resultsText = WebGUI::International::get(529); + %results = (10=>'10 '.$resultsText, 25=>'25 '.$resultsText, 50=>'50 '.$resultsText, 100=>'100 '.$resultsText); + $f = WebGUI::HTMLForm->new(1); + foreach $key (keys %{$_[0]}) { + $f->hidden($key,${$_[0]}{$key}); + } + $output = ''; + $f->raw(''); + $output .= $f->print; + $output .= '
'; + $output .= '

'.WebGUI::International::get(364).'

'; + $output .= '
'); + $f->raw(''); + $f->raw(''); + $f->raw(''); + $f->raw(''); + $f->raw(''); + $f->raw('
'.WebGUI::International::get(530).''); + $f->text('all','',$session{form}{all}); + $f->raw('
'.WebGUI::International::get(531).''); + $f->text('exactPhrase','',$session{form}{exactPhrase}); + $f->raw('
'.WebGUI::International::get(532).''); + $f->text('atLeastOne','',$session{form}{atLeastOne}); + $f->raw('
'.WebGUI::International::get(533).''); + $f->text('without','',$session{form}{without}); + $f->raw('
'); + $f->raw('
'); + $f->select("numResults",\%results,'',[$numResults]); + $f->raw('

'); + $f->submit(WebGUI::International::get(170)); + $f->raw('

'; + return $output; +} + +#------------------------------------------------------------------- + +=head2 buildConstraints ( fieldList ) { [ all, atLeastOne, exactPhrase, without ] } + + Generates and returns the constraints to an SQL where clause based + upon input from the user. + +=item fieldList + + An array reference that contains a list of the fields (table + columns) to be considered when searching. + +=item all + + A form param with a comma or space separated list of key words to + search for in the fields of the fieldList. All the words listed + here must be found to be true. + +=item atLeastOne + + A form param with a comma or space separated list of key words to + search for in the fields of the fieldList. Any of the words may + match in any of the fields for this to be true. + +=item exactPhrase + + A form param with a phrase to search for in the fields of the + fieldList. The exact phrase must be found in one of the fields + to be true. + +=item without + + A form param with a comma or space separated list of key words to + search for in the fields of the fieldList. None of the words may + be found in any of the fields for this to be true. + +=cut + +sub buildConstraints { + my ($field, $all, $allSub, $exactPhrase, $atLeastOne, $without, @words, $word, $sql); + if ($session{form}{all} ne "") { + $session{form}{all} =~ s/,/ /g; + $session{form}{all} =~ s/\s+/ /g; + @words = split(/ /,$session{form}{all}); + foreach $word (@words) { + $all .= " and " if ($all ne ""); + $all .= "("; + foreach $field (@{$_[0]}) { + $allSub .= " or " if ($allSub ne ""); + $allSub .= " $field like ".quote("%".$word."%"); + } + $all .= $allSub; + $allSub = ""; + $all .= ")"; + } + } + if ($session{form}{exactPhrase} ne "") { + foreach $field (@{$_[0]}) { + $exactPhrase .= " or " if ($exactPhrase ne ""); + $exactPhrase .= " $field like ".quote("%".$session{form}{exactPhrase}."%"); + } + } + if ($session{form}{atLeastOne} ne "") { + $session{form}{atLeastOne} =~ s/,/ /g; + $session{form}{atLeastOne} =~ s/\s+/ /g; + @words = split(/ /,$session{form}{atLeastOne}); + foreach $word (@words) { + foreach $field (@{$_[0]}) { + $atLeastOne .= " or " if ($atLeastOne ne ""); + $atLeastOne .= " $field like ".quote("%".$word."%"); + } + } + } + if ($session{form}{without} ne "") { + $session{form}{without} =~ s/,/ /g; + $session{form}{without} =~ s/\s+/ /g; + @words = split(/ /,$session{form}{without}); + foreach $word (@words) { + foreach $field (@{$_[0]}) { + $without .= " and " if ($without ne ""); + $without .= " $field not like ".quote("%".$word."%"); + } + } + } + $sql = "($all) " if ($all ne ""); + $sql .= " and " if ($sql ne "" && $exactPhrase ne ""); + $sql .= " ($exactPhrase) " if ($exactPhrase ne ""); + $sql .= " and " if ($sql ne "" && $atLeastOne ne ""); + $sql .= " ($atLeastOne) " if ($atLeastOne ne ""); + $sql .= " and " if ($sql ne "" && $without ne ""); + $sql .= " ($without) " if ($without ne ""); + return $sql; +} + + + +1; + + diff --git a/lib/WebGUI/Wobject/MessageBoard.pm b/lib/WebGUI/Wobject/MessageBoard.pm index 31b1ec2b2..9e28c0c55 100644 --- a/lib/WebGUI/Wobject/MessageBoard.pm +++ b/lib/WebGUI/Wobject/MessageBoard.pm @@ -168,6 +168,11 @@ sub www_postSave { } } +#------------------------------------------------------------------- +sub www_search { + return WebGUI::Discussion::search(); +} + #------------------------------------------------------------------- sub www_showMessage { my ($output, $submenu); @@ -179,6 +184,7 @@ sub www_showMessage { $submenu .= ''.WebGUI::International::get(22,$namespace).'
'; } + $submenu .= ''.WebGUI::International::get(364).'
'; $submenu .= ''.WebGUI::International::get(11,$namespace).'
'; $output = WebGUI::Discussion::showMessage($submenu); $output .= WebGUI::Discussion::showReplyTree(); @@ -199,7 +205,8 @@ sub www_view { $html .= ''. '
'. - WebGUI::International::get(17,$namespace).'
'; + WebGUI::International::get(17,$namespace).' · ' + .WebGUI::International::get(364).''; $html .= ''; $html .= ' diff --git a/lib/WebGUI/Wobject/UserSubmission.pm b/lib/WebGUI/Wobject/UserSubmission.pm index 2f062d837..f0c7930a3 100644 --- a/lib/WebGUI/Wobject/UserSubmission.pm +++ b/lib/WebGUI/Wobject/UserSubmission.pm @@ -130,7 +130,9 @@ sub _traditionalView { $sth->finish; $output .= '
'.WebGUI::International::get(229).' '.WebGUI::International::get(15,$namespace).'
'. '
'.WebGUI::International::get(20,$namespace).'
'; + $_[0]->get("wobjectId")).'">'.WebGUI::International::get(20,$namespace).' · ' + .WebGUI::International::get(364).''; $p = WebGUI::Paginator->new(WebGUI::URL::page(),\@row,$_[0]->get("submissionsPerPage")); $output .= ''; $output .= '
'.WebGUI::International::get(99); @@ -520,6 +522,64 @@ sub www_postSave { } } +#------------------------------------------------------------------- +sub www_search { + if ($session{form}{sid} ne "") { + return WebGUI::Discussion::search(); + } else { + my ($p, $i, $output, $constraints, $image, $sql, $sth, %submission, @row, $url); + $output = WebGUI::Search::form({wid=>"$session{form}{wid}",func=>'search'}); + $constraints = WebGUI::Search::buildConstraints([qw(username title content)]); + if ($constraints ne "") { + tie %submission, 'Tie::CPHash'; + $url = WebGUI::URL::page('func=search&wid='.$session{form}{wid} + .'&all='.WebGUI::URL::escape($session{form}{all}) + .'&exactPhrase='.WebGUI::URL::escape($session{form}{exactPhrase}).'&atLeastOne=' + .WebGUI::URL::escape($session{form}{atLeastOne}).'&numResults='.$session{form}{numResults} + .'&without='.WebGUI::URL::escape($session{form}{without})); + $output .= ''; + $output .= ''; + } + $output .= ''; + $sql = "select * from UserSubmission_submission where wobjectId=$session{form}{wid} "; + $sql .= " and ".$constraints." order by dateSubmitted desc"; + $sth = WebGUI::SQL->read($sql); + while (%submission = $sth->hash) { + $submission{title} = WebGUI::HTML::filter($submission{title},'all'); + $row[$i] = ''; + if ($_[0]->get("displayThumbnails")) { + if ($submission{image} ne "") { + $image = WebGUI::Attachment->new($submission{image},$_[0]->get("wobjectId"),$submission{submissionId}); + $row[$i] .= ''; + } else { + $row[$i] .= ''; + } + } + $row[$i] .= ''; + } + $sth->finish; + $p = WebGUI::Paginator->new($url,\@row,$session{form}{numResults}); + $output .= $p->getPage($session{form}{pn}); + $output .= '
'.WebGUI::International::get(99); + if ($_[0]->get("displayThumbnails")) { + $output .= ''.WebGUI::International::get(52,$namespace).''.WebGUI::International::get(13,$namespace). + ''.WebGUI::International::get(21,$namespace).'
+ '.$submission{title}.''; + if ($submission{userId} == $session{user}{userId}) { + $row[$i] .= ' ('.$submissionStatus{$submission{status}}.')'; + } + $row[$i] .= ''.epochToHuman($submission{dateSubmitted},"%z"). + ''.$submission{username}.'
'; + $output .= $p->getBarTraditional($session{form}{pn}); + } + return $output; + } +} + #------------------------------------------------------------------- sub www_showMessage { my ($submenu, $output); @@ -531,6 +591,8 @@ sub www_showMessage { $submenu .= ''.WebGUI::International::get(43,$namespace).'
'; } + $submenu .= '' + .WebGUI::International::get(364).'
'; $submenu .= ''.WebGUI::International::get(45,$namespace).'
'; $submenu .= ''.WebGUI::International::get(28,$namespace).'
'; @@ -595,6 +657,7 @@ sub www_viewSubmission { $output .= ''.WebGUI::International::get(47,$namespace).'
'; } + $output .= ''.WebGUI::International::get(364).'
'; $output .= ''.WebGUI::International::get(28,$namespace).'
'; $output .= '
'; #---content