Here it is.
Comments in the code are in French for now. Sorry.
There are 3 different portions of code added to the original FlexSearchForm code :
// ----------------------------
// Snippet: HyperFlexSearchForm
// ----------------------------
// Version: 0.1a
// Date: 2006.04.06
// [email protected]
//
// This snippet was designed to create a search form
// that is highly flexible in how it is presented. It
// can be used as both a small, subtle, persistent
// search field element, as well as present the search
// results. All elements are branded with classes
// for easy CSS styling.
// CONFIGURE
// MAIN SNIPPET SETUP OPTIONS
// --------------------------
// $searchStyle [ 'relevance' | 'partial' ]
// This option allows you to decide to use a faster,
// relevance sorted search ('relevance') which WILL NOT
// inlclude partial matches. Or use a slower, but
// more inclusive search ('partial') that will include
// partial matches. Results will NOT be sorted based on
// relevance.
//
// This option contributed by Rich from Snappy Graffix Media to
// allow partial matching and LIKE matching of the search term.
// [email protected]
$searchStyle = 'relevance';
// $useAllWords [ true | false ]
// If you want only documents which contain ALL words in the
// search string, set to true. Otherwise, the search will return
// all pages with ONE or more of the search words (which can be
// a LOT more pages).
$useAllWords = true;
// $showSearchWithResults [1 | 0]
// If you would like to turn off the search
// form when showing results you can set
// this to false. Can also be set in template
// by using the snippet variable: FSF_showForm
// like this (1=true, 0=false):
// [[FlexSearchForm?FSF_showForm=0]]
$showSearchWithResults = 1;
// $resultsPage [int]
// The default behavior is to show the results on
// the current page, but you may define the results
// page any way you like. The priority is:
//
// 1- snippet variable - set in page template like this:
// [[FlexSearchForm?FSF_landing=int]]
// where int is the page id number of the page you want
// your results on
// 2- querystring variable FSF_form
// 3- variable set here
// 4- use current page
//
// This is VERY handy when you want to put the search form in
// a discrete and/or small place on your page- like a side
// column, but don't want all your results to show up there!
// Set to results page or leave 0 as default
$resultsPage = 0;
// $showResults [1 | 0] (as passed in snippet variable ONLY)
// You can define whether this snippet will show the results
// of the search with it. Do this by assigning the snippet
// variable FSF_showResults as:
// [[FlexSearchForm?FSF_showResults=0]]
//
// This is useful in situations where you want to show the
// search results in a different place than the search form.
// In that type of situation, you would include two of these
// snippets on the same page, one showing results, and one
// showing the form.
//
// Default is true.
// $grabMax [ int ]
// Set to the max number of records you would like on
// each page. Set to 0 if unlimited.
$grabMax = 10;
// $pageLinkSeparator [ string ]
// What you want, if anything, between your page link numbers
$pageLinkSeparator = " | ";
// $stripHTML [ true | false ]
// Allow HTML characters in the search? Probably not.
$stripHTML = true;
// $stripSnip [ true | false ]
// Strip out snippet calls etc from the search string?
$stripSnip = true;
// $stripSnippets [ true | false ]
// Strip out snippet names so users will not be able to "search"
// to see what snippets are used in your content. This is a
// security benefit, as users will not be able to search for what pages
// use specific snippets.
$stripSnippets = true;
// $xhtmlStrict [ true | false ]
// If you want this form to validate as XHTML Strict compliance, then
// this needs to be true, but IE has a fieldset bug that I don't know
// a workaround for. So you can set this to false to avoid it.
$xhtmlStrict = false;
// $minChars [ int ]
// Minimum number of characters to require for a word to be valid for
// searching. MySQL will typically NOT search for words with less than
// 4 characters (relevance mode). If you have $useAllWords = true and
// a three or fewer word appears in the search string, the results will
// always be 0. Setting this drops those words from the search in THAT
// CIRCUMSTANCE ONLY (relevance mode, useAllWords=true).
$minChars = 4;
// LANGUAGE AND LABELS
// --------------------------
// $resultsIntroFailure
// If nothing is found for the search. You should give the user
// some indication that the search was a failure.
$resultsIntroFailure = 'There were no search results. Please try using more general terms to get more results.';
// $searchButtonText [string]
// Label the search button what
// you wish
$searchButtonText = 'Go!';
// $boxText [ string ]
// What, if anything, you want to have in the search box when the
// form first loads. When clicked, it will disappear. This uses
// JavaScript. If you don't want this feature or the JavaScript,
// just set to empty string: ''
$boxText = 'Search here...';
// $introMessage [ string ]
// This is the text that will show up if the person arrives
// at the search page without having done a search first.
// You can leave this as an empty string if you like.
$introMessage = 'Please enter a search term to begin your search.';
// $resultsFoundTextSingle, $resultsFoundTextMultiple [ string patttern ]
// The string that will tell the user how many results were found.
// two variables will be provided at runtime:
// %d The number of results found (integer)
// %s The search string itself.
$resultsFoundTextSingle = '%d result found for "%s".';
$resultsFoundTextMultiple = '%d results found for "%s".';
// $paginationTextSinglePage and $paginationTextMultiplePages [ string ]
// The text that comes before the links to other pages. In this
// example, "Result pages: " was the $paginationTextMultiplePages:
// Result pages: 1 | 2 | 3 | 4
// Page numbers will only appear if there is more than one page.
$paginationTextSinglePage = '';
$paginationTextMultiplePages = 'Result pages: ';
/* BEGIN HACK by Benjamin Toussaint [Hypernovae] */
// SEARCH IMPROVEMENTS
// --------------------------
// Separator used in the comma-separated lists
$hyperSeparator = ',';
// Name of the chunk containing the stopwords
$hyperChunk = 'stopWordList';
// Idea from xyzvisual ([email protected])
// $templateSearch [ csv ]
// Allow searching by templates
$templateSearch = '';
// $templateSearchMode [ 0 | 1 ]
// Indicates whether we exclude or include the templates list
$templateSearchMode = 1;
// Idea from Wendy Novianto
// $parentSearch [ csv ]
// Allow parent categories to be searched in
$parentSearch = '';
// $parentSearchMode [ 0 | 1 ]
// Indicates whether we exclude or include the parent categories list
$parentSearchMode = 1;
// $documentgroupSearch [ csv ]
// Allow searching by documentgroups
$documentgroupSearch = '';
// $documentgroupSearchMode [ 0 | 1 ]
// Indicates whether we exclude or include the documentgroups list
$documentgroupSearchMode = 1;
// $webgroupSearch [ csv ]
// Allow searching by webgroups
$webgroupSearch = '';
// $webgroupSearchMode [ 0 | 1 ]
// Indicates whether we exclude or include the webgroups list
$webgroupSearchMode = 1;
// $stopWords [ csv ] (from chunk)
// List of the words to exclude of the search string
$stopWords = implode(",", explode("\n", $modx->getChunk($hyperChunk)) );
/* END HACK by Benjamin Toussaint [Hypernovae] */
// Styles
// These styles are included in this snippet:
//
// .FSF_form{}
// .FSF_input {}
// .FSF_submit {}
//
// .FSF_SearchResults {}
// .FSF_resultsIntroFailure{}
// .FSF_result {}
// .FSF_resultLink {}
// .FSF_resultDescription {}
// .FSF_pagination
// .FSF_intro
// -------------
// End configure
// -------------
// establish whether to show the form or not
$showSearchWithResults = (isset($FSF_showForm))? $FSF_showForm : $showSearchWithResults;
// establish whether to show the results or not
$showResults = (isset($FSF_showResults))? $FSF_showResults : true;
// establish results page
if (isset($FSF_landing)){ // set in snippet
$searchAction = "[~".$FSF_landing."~]";
} elseif ($resultsPage > 0){ // locally set
$searchAction = "[~".$resultsPage."~]";
} else { //otherwise
$searchAction = "[~".$modx->documentIdentifier."~]";
}
// Set newline variable
$newline = "\n";
// Initialize search string
$searchString = '';
// CLEAN SEARCH STRING
if ( isset($_POST['search']) || isset($_GET['FSF_search']) ){
// Prefer post to get
$searchString = (isset($_POST['search']))? $_POST['search'] : urldecode($_GET['FSF_search']) ;
// block sensitive search patterns
$searchString =
(
$searchString != "{{" &&
$searchString != "[[" &&
$searchString != "[!" &&
$searchString != "[(" &&
$searchString != "[~" &&
$searchString != "[*"
)
?
$searchString : "" ;
// Remove dangerous tags and such
// Strip HTML too
if ($stripHTML){
$searchString = strip_tags($searchString);
}
// Regular expressions of things to remove from search string
$modRegExArray[] = '~\[\[(.*?)\]\]~'; // [[snippets]]
$modRegExArray[] = '~\[!(.*?)!\]~'; // [!noCacheSnippets!]
$modRegExArray[] = '!\[\~(.*?)\~\]!is'; // [~links~]
$modRegExArray[] = '~\[\((.*?)\)\]~'; // [(settings)]
$modRegExArray[] = '~{{(.*?)}}~'; // {{chunks}}
$modRegExArray[] = '~\[\*(.*?)\*\]~'; // [*attributes*]
// Remove modx sensitive tags
if ($stripSnip){
foreach ($modRegExArray as $mReg){
$searchString = preg_replace($mReg,'',$searchString);
}
}
// Remove snippet names
if ($stripSnippets && $searchString != ''){
// get all the snippet names
$tbl = $modx->dbConfig['dbase'] . "." . $modx->dbConfig['table_prefix'] . "site_snippets";
$snippetSql = "SELECT $tbl.name FROM $tbl;";
$snippetRs = $modx->dbQuery($snippetSql);
$snippetCount = $modx->recordCount($snippetRs);
$snippetNameArray = array();
for ($s = 0; $s < $snippetCount; $s++){
$thisSnippetRow = $modx->fetchRow($snippetRs);
$snippetNameArray[] = strtolower($thisSnippetRow['name']);
}
// Split search into strings
$searchWords = explode(' ',$searchString);
$cleansedWords = '';
foreach($searchWords as $word){
if ($word != '' &&
!in_array(strtolower($word),$snippetNameArray) &&
((!$useAllWords) ||
($searchStyle == 'partial') ||
(strlen($word) >= $minChars && $useAllWords && $searchStyle == 'relevance'))
){
$cleansedWords .= $word.' ';
}
}
// Remove last space
$cleansedWords = substr($cleansedWords,0,(strlen($cleansedWords)-1));
$searchString = $cleansedWords;
}
} // End cleansing search string
// check querystring
$validSearch = ($searchString != '')? true : false ;
//check for offset
$offset = (isset($_GET['FSF_offset']))? $_GET['FSF_offset'] : 0;
// initialize output
$SearchForm = '';
// establish form
if (($validSearch && ($showSearchWithResults)) || $showSearchWithResults){
$SearchForm .= '<form class="FSF_form" action="'.$searchAction.'" method="post">';
$SearchForm .= ($xhtmlStrict)? '<fieldset><legend>Search</legend>' : '' ;
// decide what goes in search box
$searchBoxVal = ($searchString == '' && $boxText != '')? $boxText : $searchString ;
$SearchForm .= '<input class="FSF_input" type="text" name="search" value="'.$searchBoxVal.'" ';
$SearchForm .= ($boxText)? 'onfocus="this.value=(this.value==\''.$boxText.'\')? \'\' : this.value ;" />' : '/>';
$SearchForm .= '<input class="FSF_submit" type="submit" name="sub" value="'.$searchButtonText.'" />';
$SearchForm .= ($xhtmlStrict)? '</fieldset>' : '';
$SearchForm .= '</form>'.$newline;
}
if ($showResults) {
if($validSearch) {
/*$search = explode(" ", $searchString);
$tbl = $modx->dbConfig['dbase'] . "." . $modx->dbConfig['table_prefix'] . "site_content";
if ($searchStyle == 'partial'){
$sql = "SELECT id, pagetitle, description ";
$sql .= "FROM $tbl ";
$sql .= "WHERE ";
if (count($search)>1 && $useAllWords){
foreach ($search as $searchTerm){
$sql .= "(pagetitle LIKE '%$searchString%' OR description LIKE '%$searchString%' OR content LIKE '%$searchTerm%') AND ";
}
} else {
$sql .= "(pagetitle LIKE '%$searchString%' OR description LIKE '%$searchString%' OR content LIKE '%$searchString%') AND ";
}
$sql .= "$tbl.published = 1 AND $tbl.searchable=1 AND $tbl.deleted=0;";
} else {
$sql = "SELECT id, pagetitle, description ";
$sql .= "FROM $tbl WHERE ";
if (count($search)>1 && $useAllWords){
foreach ($search as $searchTerm){
$sql .= "MATCH (pagetitle, description, content) AGAINST ('$searchTerm') AND ";
}
} else {
$sql .= "MATCH (pagetitle, description, content) AGAINST ('$searchString') AND ";
}
$sql .= "$tbl.published = 1 AND $tbl.searchable=1 AND $tbl.deleted=0;";
}*/
/* BEGIN HACK by Benjamin Toussaint [Hypernovae] */
# nettoyage de la chaîne de recherche
# caractères à remplacer
$input = "ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ";
# caractères de remplacement
$output = "aaaaaaaaaaaaooooooooooooeeeeeeeecciiiiiiiiuuuuuuuuynn";
# suppression des accents et passage en minuscules
$searchString = strtolower( strtr($searchString, $input, $output) );
# gestion des guillemets dans la chaîne de recherche
# on extrait les segments entre guillemets
$mask = '`(")(.*?)((?<!\\\)("))`s';
preg_match_all($mask, $searchString, $array);
# boucle sur toutes les occurences trouvées
foreach ($array[0] as $result)
{
# on cherche la position de la chaîne trouvée
$pos = @strpos($searchString, $result);
# on calcule sa longueur
$length = strlen($result);
# on supprimer la chaîne trouvée de la chaîne de recherche
$searchString = substr_replace($searchString, "", $pos, $length);
# on récupère ce qu'il y a entre les guillemets
$tmp = substr($result, 1, $length-2);
# si la chaîne trouvée n'est pas vide, on l'ajoute à la liste
if(!empty($tmp)) $keywords[] = $tmp;
}
$words = $stopWords;
if (!empty($words))
{
# nettoyage de la liste des mots à exclure
$clean = create_function('&$item','$item = trim(strtolower($item));');
array_walk(&$words, $clean);
# boucle sur chaque mot de la chaîne de recherche
foreach (explode(" ", $searchString) as $searchTerm)
{
# suppression des espaces dans le mot
$searchTerm = trim($searchTerm);
# si la chaîne est vide, on boucle
if (empty($searchTerm)) continue;
# on vérifie si le mot est à exclure
$test = array_search($searchTerm, $words);
# null et false pour des raisons de compatibilité PHP
# le + devant un mot permet de le garder même s'il est dans la liste noire
if ( $test === null || $test === false || $searchTerm{0} == "+" )
{
# si le mot commence par un +
if ($searchTerm{0} == "+")
{
# on supprime ce +
$searchTerm = substr($searchTerm, 1);
}
# et on ajoute le mot à la liste
$keywords[] = $searchTerm;
}
# si le mot est à exclure
elseif ( is_int($test) )
{
# on l'ajoute à la liste noire
$stopwords[] = $searchTerm;
}
}
# si la liste des mots est vide
if (!$keywords)
{
# on récupère la chaîne de départ
$keywords = explode(" ", $searchString);
$searchWarning = '';
}
# sinon, si la liste noire n'est pas vide
elseif ($stopwords)
{
# si cette liste contient in seul mot
if (count($stopwords) == 1)
{
# construction du message d'avertissement
$searchWarning = '<strong>"'.$stopwords[0].'"</strong> étant un mot très courant, il a été ignoré lors de cette recherche.';
}
# si plusieurs mots
else
{
# construction du message d'avertissement
$searchWarning = 'Les termes suivants étant très courants, ils ont été ignorés lors de cette recherche : <strong>'.implode(" ", $stopwords).'</strong>.';
}
}
}
# noms des différentes tables pour la requête
$tbl = $modx->dbConfig['dbase'] . ".`" . $modx->dbConfig['table_prefix'];
$tbl_cnt = $tbl . "site_content`";
$tbl_dgp = $tbl . "document_groups`";
$tbl_dgn = $tbl . "documentgroup_names`";
$tbl_wga = $tbl . "webgroup_access`";
$tbl_wgn = $tbl . "webgroup_names`";
$tbl_tpl = $tbl . "site_templates`";
# recherche dans les répertoires parents
# si la liste des catégorie à cherche n'est pas vide
if ( !empty($parentSearch) )
{
# construction de la requête sur les répertoires parents
$sql = "SELECT `id`, `parent`, `isfolder`, `pagetitle` FROM `modx_site_content` WHERE `parent` <> '0' OR `isfolder` = '1'";
$rs = $modx->dbQuery($sql);
$folders = array();
while ( $doc = mysql_fetch_object($rs) )
{
# on regroupe les résultats par id de dossier parent
$folders[$doc->parent][] = array("id" => $doc->id, "isfolder" => $doc->isfolder);
}
# fonction qui renvoit la liste des sous-dossiers
$list = array();
# id du dossier parent, liste générée plus haut
function getSubfolders($parentId, $folders)
{
global $list;
# si le dossier contient des sous-dossiers
if (is_array($folders[$parentId]))
{
# boucle sur chaque sous-dossier
foreach ($folders[$parentId] as $item)
{
# si le sous-dossier n'est pas vide
if ($item["isfolder"])
{
# on récupère l'id du sous-dossier
$list[] = (int) $parentId;
# et on fait une nouvelle recherche avec cet id
getSubfolders($item["id"], $folders);
}
}
# liste des sous-dossiers
$list[] = (int) $parentId;
}
# on renvoit la liste des sous-dossiers
return $list;
}
# recherche des sous-dossiers
# boucle sur chaque id dans la liste à chercher
foreach (explode($hyperSeparator, $parentSearch) as $parentId)
{
$parentId = (int) $parentId;
# on recherche les sous-dossiers de chaque répertoire
$subfolders[] = getSubfolders($parentId, $folders);
}
# suppression des doublons dans la liste reçue
$parentSearchArr = array_unique($subfolders);
}
# construction de la requête de base
$sql = "SELECT ";
$sql .= "cnt.`id`, cnt.`pagetitle`, cnt.`description`";
# si le liste des templates n'est pas vide
if ( !empty($templateSearch) )
{
$sql .= ", cnt.`parent`";
}
# si le liste des groupes de documents ou celle des groupes web n'est pas vide
if ( ( !empty($documentgroupSearch) ) || ( !empty($webgroupSearch) ) )
{
$sql .= ", dgn.`name` AS documentgroup";
# si la liste des groupes web n'est pas vide
if ( !empty($webgroupSearch) )
{
$sql .= ", wgn.`name` AS webgroup";
}
}
# si la liste des templates n'est pas vide
if ( !empty($templateSearch) )
{
$sql .= ", stm.`templatename` AS template";
}
$sql .= " FROM $tbl_cnt AS cnt";
# si le liste des groupes de documents ou celle des groupes web n'est pas vide
if ( ( !empty($documentgroupSearch) ) || ( !empty($webgroupSearch) ) )
{
$sql .= " LEFT JOIN $tbl_dgp AS dgp ON cnt.`id` = dgp.`document`";
$sql .= " LEFT JOIN $tbl_dgn AS dgn ON dgp.`document_group` = dgn.`id`";
# si la liste des groupes web n'est pas vide
if ( !empty($webgroupSearch) )
{
$sql .= " LEFT JOIN $tbl_wga AS wga ON dgn.`id` = wga.`documentgroup`";
$sql .= " LEFT JOIN $tbl_wgn AS wgn ON wga.`webgroup` = wgn.`id`";
}
}
# si la liste des templates n'est pas vide
if ( ( !empty($templateSearch) ) )
{
$sql .= " LEFT JOIN $tbl_tpl AS stm ON cnt.`template` = stm.`id`";
}
$sql .= " WHERE ";
# filtres de base
$sql .= "cnt.`published` = '1' AND cnt.`searchable` = '1' AND cnt.`deleted` = '0'";
# fonction qui construit la requête sur base de la liste (csv)
# nom du champ, liste, mode de recherche
function csvToQuery($name, $csv, $mode)
{
# paramètres variables selon le mode (inclusion ou exclusion)
$compStr = ($mode) ? "=" : "<>";
$joinStr = ($mode) ? "OR" : "AND";
# boucle sur chaque éléments de la liste
foreach (explode($hyperSeparator, $csv) as $val)
{
$group = trim($val);
# requête brute
$q[] = "$name $compStr '$val'";
}
# requête finale
$sql = " AND (" . implode(" $joinStr ", $q) . ") ";
# on renvoit le segment de requête
return $sql;
}
# filtre sur les templates
# si la liste des templates n'est pas vide
if ( !empty($templateSearch) )
{
# on construit la requête
$sql .= csvToQuery("template", $templateSearch, $templateSearchMode);
}
# filtre sur les dossiers parents
# si la liste des dossiers parents n'est pas vide
if ( !empty($parentSearch) )
{
# on récupère les id des dossiers et sous-dossiers
$parentSearch = implode(",", $parentSearchArr);
# on construit la requête
$sql .= csvToQuery("parent", $parentSearch, $parentSearchMode);
}
# filtre sur les groupes de documents
# si la liste de groupes de documents n'est pas vide
if ( !empty($documentgroupSearch) )
{
# on construit la requête
$sql .= csvToQuery("documentgroup", $documentgroupSearch, $documentgroupSearchMode);
}
# filtre sur les groupes web
# si la liste des groupes web n'est pas vide
if ( !empty($webgroupSearch) )
{
# on construit la requête
$sql .= csvToQuery("webgroup", $webgroupSearch, $webgroupSearchMode);
}
# filtre sur le mots-clés (pour finir en beauté)
# fontion qui protège les valeurs reçues
function smartEscape($value)
{
if (get_magic_quotes_gpc())
{
# suppression des antislashs
$value = stripslashes($value);
}
if (!is_numeric($value))
{
# protection de la chaîne
$value = "'". mysql_real_escape_string($value) . "'";
}
# on renvoit la chaîne protégée
return $value;
}
# boucle sur chaque mot
foreach ($keywords as $searchTerm)
{
# si le mot est précédé d'un - (moins)
if ( $searchTerm{0} == "-" )
{
# paramètre variable selon le style de recherche
$compStr = ($searchStyle == 'partial') ? "NOT LIKE" : "<>" ;
$joinStr = "AND";
# on supprime le - en début de mot
$searchTerm = substr($searchTerm, 1);
}
# s'il n'est pas précédé d'un -
else
{
# paramètre variable selon le style de recherche
$compStr = ($searchStyle == 'partial') ? "LIKE" : "=";
$joinStr = "OR";
}
# selon le style de recherche, on inclut le mot entre %
$searchTerm = ($searchStyle == 'partial') ? "%" . $searchTerm . "%" : $searchTerm ;
# on protège la chaîne pour la requête
$searchTerm = smartEscape($searchTerm);
# construction de la reqûete
$q[] = " (LOWER(cnt.`pagetitle`) $compStr $searchTerm $joinStr LOWER(cnt.`description`) $compStr $searchTerm $joinStr LOWER(cnt.`content`) $compStr $searchTerm) ";
}
# paramètre variable selon l'option choisie
$joinStr = ($useAllWords) ? "AND" : "OR" ;
# dans le cas où il n'y a qu'un seul mot
if (count($q) == 1)
{
$sql .= " AND (" . $q[0] . ") ";
}
# si plusieurs mots
elseif (count($q) > 1)
{
$sql .= " AND (" . implode(" $joinStr ", $q) . ") ";
}
/* END HACK by Benjamin Toussaint [Hypernovae] */
$rs = $modx->dbQuery($sql);
$limit = $modx->recordCount($rs);
if($limit>0) {
$SearchForm .= '<div class="FSF_searchResults">'.$newline;
// pagination
if ($grabMax > 0){
$numResultPages = ceil($limit/$grabMax);
$resultPageLinks = '<span class="FSF_pages">';
$resultPageLinks .= ($limit>$grabMax)? $paginationTextMultiplePages : $paginationTextSinglePage ;
$resultPageLinkNumber = 1;
for ($nrp=0;$nrp<$limit && $limit > $grabMax;$nrp+=$grabMax){
if($offset == ($resultPageLinkNumber-1)*$grabMax){
$resultPageLinks .= $resultPageLinkNumber;
} else {
$resultPageLinks .= '<a href="[~' . $modx->documentObject['id'] . '~]&FSF_offset=' . $nrp . '&FSF_search=' . urlencode($searchString) . '">' . $resultPageLinkNumber . '</a>';
}
$resultPageLinks .= ($nrp+$grabMax < $limit)? $pageLinkSeparator : '' ;
$resultPageLinkNumber++;
}
$resultPageLinks .= "</span>".$newline;
$SearchForm .= '<p class="FSF_pagination">';
$resultsFoundText = ($limit > 1)? $resultsFoundTextMultiple : $resultsFoundTextSingle ;
$SearchForm .= sprintf($resultsFoundText,$limit,$searchString);
/* BEGIN HACK by Benjamin Toussaint [Hypernovae] */
# on affiche l'avertissement sur les mots exclus de la recherche
$SearchForm .= '<br /><span class="FSF_Warning">'.$hyperSearchWarning.'</span>';
/* END HACK by Benjamin Toussaint [Hypernovae] */
$SearchForm .= '<br />'.$resultPageLinks."</p>".$newline;
} // end if grabMax
// search results
$useLimit = ($grabMax > 0)? $offset+$grabMax : $limit;
for ($y = $offset; ($y < $useLimit) && ($y<$limit); $y++) {
$moveToRow = mysql_data_seek($rs,$y);
$SearchFormsrc=$modx->fetchRow($rs);
$SearchForm.='<div class="FSF_result">'.$newline;
$SearchForm.='<a class="FSF_resultLink" href="[~'.$SearchFormsrc['id'].'~]" title="' . $SearchFormsrc['pagetitle'] . '">' . $SearchFormsrc['pagetitle'] . "</a>".$newline;
$SearchForm.=$SearchFormsrc['description']!='' ? '<span class="FSF_resultDescription">' . $SearchFormsrc['description'] . "</span>".$newline : "" ;
$SearchForm.='</div><!--end FlexSearchResult-->'.$newline;
}
$SearchForm.='<p class="FSF_pagination">'.$resultPageLinks.'</p>';
$SearchForm.='</div><!--end FlexSearchResults-->'.$newline;
} else {
$SearchForm.='<p class="FSF_resultsIntroFailure">'.$resultsIntroFailure.'</p>';
} // end if records found
} else if (!$validSearch && isset($_POST['sub'])) {
// message to show if search was performed but for something invalid
$SearchForm .= '<p class="FSF_resultsIntroFailure">'.$resultsIntroFailure.'</p>';
} else { // end if validSearch
$SearchForm .= '<p class="FSF_intro">'.$introMessage.'</p>';
} // end if not validSearch
} // end if showResults
return $SearchForm;