# Module of TWiki Enterprise Collaboration Platform, http://TWiki.org/ # # Copyright (C) 1999-2007 Peter Thoeny, peter@thoeny.org # and TWiki Contributors. All Rights Reserved. TWiki Contributors # are listed in the AUTHORS file in the root of this distribution. # NOTE: Please extend that file, not this notice. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. For # more details read LICENSE in the root of this distribution. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # As per the GPL, removal of this notice is prohibited. =begin twiki ---+ package TWiki::UI::Search UI functions for searching. =cut package TWiki::UI::Search; use strict; use TWiki; use TWiki::UI; =pod ---++ StaticMethod search( $session ) Perform a search as dictated by CGI parameters: | *Parameter:* | *Description:* | *Default:* | | ="text"= | Search term. Is a keyword search, literal search or regular expression search, depending on the =type= parameter. SearchHelp has more | required | | =search="text"= | (Alternative to above) | N/A | | =web="Name"=
=web="%MAINWEB%, Know"=
=web="all"= | Comma-separated list of webs to search. The special word =all= means all webs that doe *not* have the =NOSEARCHALL= variable set to =on= in their %WEBPREFSTOPIC%. You can specifically *exclude* webs from an =all= search using a minus sign - for example, =web="all,-Secretweb"=. | Current web | | =topic="%WEBPREFSTOPIC%"=
=topic="*Bug"= | Limit search to topics: A topic, a topic with asterisk wildcards, or a list of topics separated by comma. | All topics in a web | | =excludetopic="Web*"=
=excludetopic="%HOMETOPIC%, WebChanges"= | Exclude topics from search: A topic, a topic with asterisk wildcards, or a list of topics separated by comma. | None | | =type="keyword"=
=type="literal"=
=type="regex"= | Do a keyword search like =soap "web service" -shampoo=; a literal search like =web service=; or RegularExpression search like =soap;web service;!shampoo= | =%SEARCHVAR- DEFAULTTYPE%= [[TWikiPreferences][preferences]] setting (%SEARCHVARDEFAULTTYPE%) | | =scope="topic"=
=scope="text"=
=scope="all"= | Search topic name (title); the text (body) of topic; or all (both) | ="text"= | | =order="topic"=
=order="created"=
=order="modified"=
=order="editby"=
=order=
 "formfield(name)"= | Sort the results of search by the topic names, topic creation time, last modified time, last editor, or named field of TWikiForms. The sorting is done web by web; in case you want to sort across webs, create a [[FormattedSearch][formatted]] table and sort it with TablePlugin's initsort | Sort by topic name | | =limit="all"=
=limit="16"= | Limit the number of results returned. This is done after sorting if =order= is specified | All results | | =date="..."= | limits the results to those pages with latest edit time in the given TimeInterval. | All results | | =reverse="on"= | Reverse the direction of the search | Ascending search | | =casesensitive="on"= | Case sensitive search | Ignore case | | =bookview="on"= | BookView search, e.g. show complete topic text | Show topic summary | | =nonoise="on"= | Shorthand for =nosummary="on" nosearch="on" nototal="on" zeroresults="off" noheader="on" noempty="on"= | Off | | =nosummary="on"= | Show topic title only | Show topic summary | | =nosearch="on"= | Suppress search string | Show search string | | =noheader="on"= | Suppress search header
*Topics: Changed: By:* | Show search header | | =nototal="on"= | Do not show number of topics found | Show number | | =zeroresults="off"= | Suppress all output if there are no hits | =zeroresults="on"=, displays: "Number of topics: 0" | | =noempty="on"= | Suppress results for webs that have no hits. | Show webs with no hits | | =header="..."=
=format="..."= | Custom format results: see *[[FormattedSearch]]* for usage, variables & examples | Results in table | | =expandvariables="on"= | Expand variables before applying a FormattedSearch on a search hit. Useful to show the expanded text, e.g. to show the result of a SpreadSheetPlugin =%CALC{}%= instead of the formula | Raw text | | =multiple="on"= | Multiple hits per topic. Each hit can be [[FormattedSearch][formatted]]. The last token is used in case of a regular expression ";" _and_ search | Only one hit per topic | | =nofinalnewline="on"= | If =on=, the search variable does not end in a line by itself. Any text continuing immediately after the search tag on the same line will be rendered as part of the table generated by the search, if appropriate. | =off= | | =separator=", "= | Line separator between hits | Newline ="$n"= | =cut sub search { my $session = shift; my $query = $session->{cgiQuery}; my $webName = $session->{webName}; my $topic = $session->{topicName}; TWiki::UI::checkWebExists( $session, $webName, $topic, 'search' ); # The CGI.pm docs claim that it returns all of the values in a # multiple select if called in a list context, but that may not # work (didn't on the dev box -- perl 5.004_4 and CGI.pm 2.36 on # Linux (Slackware 2.0.33) with Apache 1.2. That being the case, # we need to parse them out here. # my @webs = $query->param( 'web' ) || ( $webName ); #doesn't work # Note for those unused to Perlishness: # ------------------------------------- # The pipeline at the end of this assignment splits the full query # string on '&' or ';' and selects out the params that begin with 'web=', # replacing them with whatever is after that. In the case of a # single list of webs passed as a string (say, from a text entry # field) it does more processing than it needs to to get the # correct string, but so what? The pipline is the second # parameter to the join, and consists of the last two lines. The # join takes the results of the pipeline and strings them back # together, space delimited, which is exactly what &searchWeb # needs. # Note that mod_perl/cgi appears to use ';' as separator, whereas plain cgi uses '&' my $attrWeb = join ' ', grep { s/^web=(.*)$/$1/ } split(/[&;]/, $query->query_string); # need to unescape URL-encoded data since we use the raw query_string # suggested by JeromeBouvattier $attrWeb =~ tr/+/ /; # pluses become spaces $attrWeb =~ s/%([0-9a-fA-F]{2})/pack('c',hex($1))/ge; # %20 becomes space # $session->writePageHeader(); # SMELL: what's all the 'scalar' crud, below? my $text = $session->{search}->searchWeb( # _callback => \&_contentCallback, #FIXME - can't process format=| $topic | line by line... _callback => undef, _cbdata => undef, 'inline' => 0, 'search' => scalar $query->param( 'search' ), 'web' => $attrWeb, 'topic' => scalar $query->param( 'topic' ), 'excludetopic' => scalar $query->param( 'excludetopic' ), 'scope' => scalar $query->param( 'scope' ), 'order' => scalar $query->param( 'order' ), 'type' => scalar $query->param( 'type' ) || $session->{prefs}->getPreferencesValue( 'SEARCHDEFAULTTTYPE' ), 'regex' => scalar $query->param( 'regex' ), 'limit' => scalar $query->param( 'limit' ), 'reverse' => scalar $query->param( 'reverse' ), 'casesensitive' => scalar $query->param( 'casesensitive' ), 'nosummary' => scalar $query->param( 'nosummary' ), 'nosearch' => scalar $query->param( 'nosearch' ), 'noheader' => scalar $query->param( 'noheader' ), 'nototal' => scalar $query->param( 'nototal' ), 'bookview' => scalar $query->param( 'bookview' ), 'showlock' => scalar $query->param( 'showlock' ), 'expandvariables' => scalar $query->param( 'expandvariables' ), 'noempty' => scalar $query->param( 'noempty' ), 'template' => scalar $query->param( 'template' ), 'header' => scalar $query->param( 'header' ), 'format' => scalar $query->param( 'format' ), 'multiple' => scalar $query->param( 'multiple' ), 'separator' => scalar $query->param( 'separator' ), 'subweb' => scalar $query->param( 'subweb' ) ); $session->writeCompletePage($text); } sub _contentCallback { TWiki::spamProof( $_[1] ); #FIXME: if you're going to define a callback, you have to convert from TML too print $_[1]; } 1;