Source de search.inc

<?

define
("DEFAULT_INPUT_VALUE",' mots à rechercher');
define("CONTENT_PATTERN_BEGIN",'setContent(\'');
define("CONTENT_PATTERN_END",'\'->display();');
define("TITLE_PATTERN",'/setTitle[(]"(.*)"[)];/');
define("IGNORE_MARKUP_PATTERN","(?![^<]*[>])");
define('IGNORE_TEXTAREA_PATTERN','(<textarea.*?>)(.*?<em.*?onclick.*?>(.*?)<\/em>.*?)*?(<\/textarea>)');
define("EXTRACT_SEMI_SIZE",40);
define("IGNORED_FILES","search\.php|news\.php|error\.php|display_script\.php|display_source\.php");
define("SEARCH_LOG_FILE","log/search.log.");
define("HIGHLIGHT_STYLE_COUNT",5);
define("MAX_WORDS",10);
define("SEARCH_ACCESSKEY",4);
define("TAB_INDEX_QUICK_INPUT",5);
define("TAB_INDEX_QUICK_SUBMIT",6);

$searchCount = 0;
$searchStyle = '';

function 
highlightExpression($matched)
{
  global 
$searchCount;
  global 
$searchStyle;

  
$searchCount++;
  
$result = '<em title="Cliquez pour voir le résultat suivant" onclick="return gotoFound('.($searchCount + 1).')" id="found_'.$searchCount.'" class="'.$searchStyle.'">'.$matched[0].'</em>';
  return 
$result;
}

function 
cleanTextArea($matched)
{
  
$result = preg_replace('/<em.*onclick.*>(.*)<\/em>/U','\\1',$matched[0]);
  return 
$result;
}

function 
highlightText(&$text, $inputWords, $withPreg = false, $caseSensitive = false)
{
  global 
$searchCount;
  global 
$searchStyle;
  
$words = getWords($excludedWords, $withPreg, $inputWords, false);
  if (!
is_array($words))
  {
    return;
  }

  
$text = "</div>" . $text;
  
$words = array_reverse($words, true);

  if (
$caseSensitive)
  {
    
$caseIndicator = "";
  }
  else
  {
    
$caseIndicator = "i";
  }
  while (list(
$index, $word) = each($words))
  {
    
$searchCount++;
    
$searchStyle = "highlight".($index % HIGHLIGHT_STYLE_COUNT);
    
$currentSearchCount = $searchCount;
    
//$text = preg_replace("/".$word.IGNORE_MARKUP_PATTERN."/".$caseIndicator, "<em class=\"$style\">\\0</em>", $text);

    
$text = preg_replace_callback("/".$word.IGNORE_MARKUP_PATTERN."/".$caseIndicator, 'highlightExpression', $text);

    
$text = preg_replace_callback('/<textarea.*>.*<\/textarea>/Us', 'cleanTextArea', $text);
    
$text = '<em title="Cliquez pour voir le résultat suivant" onclick="return gotoFound('.($currentSearchCount + 1).")\" id=\"found_$currentSearchCount\" class=\"$searchStyle\">".stripslashes($word) . "</em> " . $text;
  }
  
$text = "<div class=\"highlighted\">" . $text;
}


function 
logSearch($searchQuery)
{
  
$fd = fopen(SEARCH_LOG_FILE.date("d.m.Y"), "a");
  
fwrite ($fd, $_SERVER["REMOTE_ADDR"]." : ".$searchQuery."\n");
  
fclose ($fd);
}

function 
getWords(&$badWords, $withPreg = false, $cgiVar = "query", $isGetNeeded = true)
{
  if (
$isGetNeeded)
  {
    
$inputWords = $_GET[$cgiVar];
  }
  else
  {
    
$inputWords = $cgiVar;
  }

  
$cleanedWords = preg_replace('/\b&[a-z]+;\b/', ' ',strip_tags($inputWords));

  
$wordCount = 0;
  
$badWordCount = 0;

  
// Extraire les expressions exactes
  
$curr_pos = 0;
  
$first_found = false;
  
$expr_begin = 0;
  while (
$curr_pos !== false)
  {
    
$curr_pos = strpos($cleanedWords, '"', $curr_pos);
    if (
$curr_pos === false)
    {
    break;
    }
    if (
$first_found)
    {
      
$expr_end = $curr_pos - 1;
      
$words[$wordCount] = substr($cleanedWords, $expr_begin, $expr_end - $expr_begin);
      
$wordCount++;
      
$cleanedWords = substr($cleanedWords, 0, max($expr_begin - 2, 0)).substr($cleanedWords, $expr_end+2);
      
$first_found = false;
      
$curr_pos = 0;
    }
    else
    {
      
$expr_begin = ++$curr_pos;
      
$first_found = true;
    }
  }

  
$allWords = explode(" ", $cleanedWords);

  while (list(
$index, $word) = each($allWords)) 
  {
    if ((
strlen($word) > 1) && ($wordCount < MAX_WORDS))
    {
      if (
$withPreg)
      {
        
$words[$wordCount] = $word;
      }
      else
      {
        
$words[$wordCount] = preg_quote(stripslashes($word));
      }
      
$wordCount++;
    }
    else if ((
$word != " ") && (strlen($word) != 0))
    {
      
$badWords[$badWordCount] = $word;
      
$badWordCount++;
    }
  }

  return 
array_unique($words);
}

function 
getSearchEngineWords()
{
  
$result = "";

  if (!isset(
$_SERVER["HTTP_REFERER"]))
  {
    return 
$result;
  }

  if ( (
$_SERVER["HTTP_REFERER"] != "") && ( (eregi($_SERVER["HTTP_HOST"].'/rechercher.php',$_SERVER["HTTP_REFERER"]) !== false)  || (eregi($_SERVER["SERVER_NAME"], $_SERVER["HTTP_REFERER"]) === false)) )
  {
    
$url=$_SERVER["HTTP_REFERER"];
    
// Recherche interne
    
if (eregi($_SERVER["SERVER_NAME"],$url) !== false)
    {
      if(
$_SERVER['PHP_SELF'] == '/rechercher.php')
      {
        return 
$result;
      }
      
preg_match("'query=(.*?)(&| )'si", " $url ", $keywords);
      if (!isset(
$keywords[1]))
      {
        return 
$result;
      }
      if (
eregi('with_preg=on',$_SERVER["HTTP_REFERER"]) )
      {
        
$_GET['with_preg'] = "on";
      }
      else
      {
        
$_GET['with_preg'] = "off";
      }
      if (
eregi('with_case=on',$_SERVER["HTTP_REFERER"]) )
      {
        
$_GET['with_case'] = "on";
      }
      else
      {
        
$_GET['with_case'] = "off";
      }
    }
    
// Google, AllTheWeb, MSN, Freeserve, Altavista, club-internet
    
else if ((eregi("www\.google",$url) !== false) or (eregi("www\.alltheweb",$url) !== false) or (eregi("search\.msn",$url) !== false) or (eregi("ifind\.freeserve",$url) !== false) or (eregi("altavista\.com",$url) !== false) or (eregi("recherche\.club-internet",$url) !== false))
    {
      
preg_match("'q=(.*?)(&| )'si", " $url ", $keywords);
    }
    
// HotBot, Lycos, Netscape, AOL
    
else if ((eregi("www\.hotbot",$url) !== false) or (eregi("search\.lycos",$url) !== false) or (eregi("vachercher\.lycos",$url) !== false) or (eregi("search\.netscape",$url) !== false) or (eregi("aolsearch\.aol",$url) !== false))
    {
      
preg_match("'query=(.*?)(&| )'si", " $url ", $keywords);
    }
    
// Yahoo
    
else if ((eregi("yahoo\.com",$url) !== false) or (eregi("search\.yahoo",$url) !== false))
    {
      
preg_match("'p=(.*?)(&| )'si", " $url ", $keywords);
    }
    
// Looksmart
    
else if (eregi("looksmart\.com",$url) !== false)
    {
      
preg_match("'key=(.*?)(&| )'si", " $url ", $keywords);
    }
    
// DMOZ
    
else if (eregi("search\.dmoz",$url) !== false)
    {
      
preg_match("'search=(.*?)(&| )'si", " $url ", $keywords);
    }
    
// Ask
    
else if (eregi("ask\.co",$url) !== false)
    {
      
preg_match("'ask=(.*?)(&| )'si", " $url ", $keywords);
    }

    
$result = addslashes(urldecode($keywords[1]));

    
$result = str_replace(" +", " ", $result);

    
$tmp_result = utf8_decode($result);

    if (
utf8_encode($tmp_result) == $result)
    {
      
$result = $tmp_result;
    }

  }

  return 
$result;
}

function 
getQuickSearchForm($forum = "", $forumTitle = "")
{
  if (
$forum == "")
  {
    
$where = 'sur ce site';
  }
  else
  {
    if (
$forum == "all")
    {
      
$where = 'dans tous les forums';
    }
    else
    {
      
$where = 'dans le forum '.$forumTitle;
    }
  }

  
$result = ' <form action="/rechercher.php#results" method="get">
  <div>
   <label for="quick_query_text">Rechercher</label>
   <input id="quick_query_text" type="text" tabindex="'
.TAB_INDEX_QUICK_INPUT.'" accesskey="'.SEARCH_ACCESSKEY.'" name="query" maxlength="256" size="20" title="Entrez une liste de mots à rechercher '.$where.'" value="'.DEFAULT_INPUT_VALUE.'" onfocus="return clearInput(this,\''.DEFAULT_INPUT_VALUE.'\')" />&nbsp;
   <input type="submit" class="submit-button" tabindex="'
.TAB_INDEX_QUICK_SUBMIT.'" value="OK" title="Lancer la recherche" />
   <input type="hidden" name="type" value="AND" />
'
;

  if ( ((
strlen(session_id())) != 0) && (!isset($_COOKIE[session_name()])) )
  {
    
$result .= '   <input type="hidden" name="'.session_name().'" value="'.session_id().'" />
'
;
  }

  if (
$forum != "")
  {
   
$result .= '   <input type="hidden" name="forum" value="'.$forum.'" />
   <input type="hidden" name="zone" value="forum" />'
;
  }
    
  
$result .= "\n  </div>\n </form>\n";

  return 
$result;
}

function 
getSearchForm($words = "", $searchType="GET", $withPreg="GET", $withCase="GET", $searchZone="GET")
{
  if (!
$words)
  {
    
$words = DEFAULT_INPUT_VALUE;
  }

  
$words = str_replace('"',"&quot;",stripslashes($words));

  if (
$searchType == "GET")
  {
    
$requestedSearchType = (isset($_GET["type"]) ? $_GET["type"] : "");
  }
  else
  {
    
$requestedSearchType = $searchType;
  }

  if (
$searchZone == "GET")
  {
    
$requestedSearchZone = (isset($_GET["zone"]) ? $_GET["zone"] : "site");
  }
  else
  {
    
$requestedSearchZone = $searchzone;
  }

  if (
$withPreg == "GET")
  {
    
$requestedPreg = isset($_GET["with_preg"]) ? $_GET["with_preg"] : "";
  }
  else
  {
    
$requestedPreg = $withPreg;
  }

  if (
$withCase == "GET")
  {
    
$requestedCase = isset($_GET["with_case"]) ? $_GET["with_case"] : "";
  }
  else
  {
    
$requestedCase = $withCase;
  }

  if (
$requestedSearchType == "OR")
  {
    
$orChecked = "checked=\"checked\"";
    
$andChecked = "";
  }
  else
  {
    
$andChecked = "checked=\"checked\"";
    
$orChecked = "";
  }

  if (
$requestedSearchZone == "forum")
  {
    
$forumChecked = "checked=\"checked\"";
    
$siteChecked = "";
  }
  else
  {
    
$siteChecked = "checked=\"checked\"";
    
$forumChecked = "";
  }

  if (
$requestedPreg == "on")
  {
    
$pregChecked = "checked=\"checked\"";
  }
  else
  {
    
$pregChecked = ""; 
  } 

  if (
$requestedCase == "on")
  {
    
$caseChecked = "checked=\"checked\"";
  }
  else
  {
    
$caseChecked = "";
  }

  
$forums = new Forums();

  
$result = "  <script type=\"text/javascript\" src=\"/js/search_utils.js\"></script>
  <form action=\"/rechercher.php#results\" method=\"get\" class=\"search\">
   <div>
    <label for=\"query_text\"><strong>Recherche :</strong> </label>
    <input id=\"query_text\" type=\"text\" accesskey=\""
.SEARCH_ACCESSKEY."\" name=\"query\" maxlength=\"256\" size=\"40\" value=\"$words\" onfocus=\"return clearInput(this,'".DEFAULT_INPUT_VALUE."')\" title=\"Entrez ici les mots à rechercher\" /><br />
   </div>
   <fieldset>
    <legend>Portée de la recherche<br /></legend>
    <input id=\"site\" type=\"radio\" name=\"zone\" value=\"site\" 
$siteChecked title=\"Cocher cette case pour que la recherche soit lancée sur le site\" />
    <label id=\"siteL\" for=\"site\" title=\"Cocher cette case pour que la recherche soit lancée sur le site\">Rechercher sur le <strong>site</strong>.</label><br />
    <input id=\"forums\" type=\"radio\" name=\"zone\" value=\"forum\" 
$forumChecked title=\"Cocher cette case pour que la recherche soit lancée sur le ou les forums\" />
    <label id=\"forumsL\" for=\"forums\" title=\"Cocher cette case pour que la recherche soit lancée sur le ou les forums\">Rechercher sur </label><label id=\"selectL\" for=\"select-forum\" title=\"Cocher cette case pour que la recherche soit lancée sur le ou les forums\">le <strong>forum</strong> </label>"
.$forums->getForumsDropDown().
"   </fieldset>
   <fieldset>
    <legend>Type de recherche<br /></legend>
    <input id=\"and\" type=\"radio\" name=\"type\" value=\"AND\" 
$andChecked title=\"Seules les pages contenant tous les mots seront retournées\" />
    <label for=\"and\" title=\"Seules les pages contenant tous les mots seront retournées\">Rechercher <strong>tous</strong> ces mots.</label><br />
    <input id=\"or\" type=\"radio\" name=\"type\" value=\"OR\" 
$orChecked title=\"Les pages contenant un ou plusieurs des mots seront retournées\" />
    <label for=\"or\" title=\"Les pages contenant un ou plusieurs des mots seront retournées\">Rechercher <strong>au moins un</strong> de ces mots.</label>"
;
  if ( ((
strlen(session_id())) != 0) && (!isset($_COOKIE[session_name()])) )
  {
    
$result .= "   <input type=\"hidden\" name=\"".session_name()."\" value=\"".session_id()."\" />";
  }
  
$result .= "   </fieldset>
   <fieldset>
    <legend>Options avancées<br /></legend>
    <input id=\"case\" type=\"checkbox\" name=\"with_case\" 
$caseChecked title=\"Permet de faire la distinction entre majuscules et minuscules\" />
    <label id=\"caseL\" for=\"case\" title=\"Permet de faire la distinction entre majuscules et minuscules\">Recherche sensible à la casse.</label><br />
    <input id=\"preg\" type=\"checkbox\" name=\"with_preg\" 
$pregChecked title=\"Le texte à rechercher sera considéré comme une expression régulière Perl\" />
    <label id=\"pregL\" for=\"preg\" title=\"Le texte à rechercher sera considéré comme une expression régulière Perl\">Utiliser les expressions régulières Perl.</label>
   </fieldset>
   <div>
    <input type=\"submit\" class=\"submit-button\" value=\"Lancer la recherche\" title=\"Cette page sera ré-affichée avec les résultats de la recherche\" />
   </div>
  </form>
  <script type=\"text/javascript\">initSearch('
$requestedSearchZone');</script>
"
;
  return 
$result;
}

function 
getTextContent($filename)
{
  
$fd = fopen ($filename, "r");
  
$fileContent = fread ($fd, filesize ($filename));

  
$beginHTML = strpos($fileContent, CONTENT_PATTERN_BEGIN) + strlen(CONTENT_PATTERN_BEGIN);
  
$lengthHTML = strpos($fileContent, CONTENT_PATTERN_END) - $beginHTML;
  
$fileContent = substr($fileContent, $beginHTML, $lengthHTML);
  
$textContent = stripSlashes(strip_tags($fileContent));
  
$replaceArray = array('&nbsp;', '$header->format()', '$currentPage->setPageTitle(', '$currentPage->setIntroduction(', '$currentPage->addChapter(');
  
$textContent = str_replace($replaceArray, " ", $textContent);

  
fclose ($fd);

  return 
$textContent;
  
$textContent = getTitle($filename).getHeader($filename).$textContent;
}

function 
getTitle($filename)
{
  
$result = "";

  
$lessons = new Lessons();
  
$lessonId = basename($filename, ".php");

  if (
$lessons->lessonExists($lessonId))
  {
    
$lessonInfo = $lessons->lessonsList[$lessonId];
    
$result = $lessonInfo->title." - [".$lessons->categoriesList[$lessonInfo->category]->abbr."]";
  }
  else
  {
    
$fd = fopen($filename, "r");
    
$fileContent = fread($fd, filesize($filename));
    
preg_match(TITLE_PATTERN, $fileContent, $title);
    
$result = $title[1];
  }
  return 
$result;
}

function 
getHeader($filename)
{
  
$result = "";

  
$lessons = new Lessons();
  
$lessonId = basename($filename, ".php");

  if (
$lessons->lessonExists($lessonId))
  {
      
$lessonInfo = $lessons->lessonsList[$lessonId];
      
$lessonPage = new LessonPage($lessonId);
      
$result = strip_tags($lessonPage->lessonHeader->format());
  }

  return 
$result;
}

function 
countOccurences($text, $pattern, &$firstExtract, $caseSensitive = false)
{
  
$pattern = ereg_replace("([^\])/","\\1\/",$pattern);
  
$pattern = ereg_replace("//","/\/",$pattern);

  if (
$caseSensitive)
  {
    
$count = preg_match_all("/$pattern/", $text, $matches);
  }
  else
  {
    
$count = preg_match_all("/$pattern/i", $text, $matches);
  }
  if (
$count)
  {
      
$occur = $matches[0][0];
      
$begin = strpos($text, $occur);
      
$firstExtract = substr($text, max($begin - EXTRACT_SEMI_SIZE, 0), strlen($occur) + (2 * EXTRACT_SEMI_SIZE));
      
$firstExtract = str_replace($occur, "<strong>$occur</strong>", $firstExtract);
  }
  return 
$count;
}

class 
SearchResult
{
    var 
$url;
    var 
$wordsResult;
    var 
$words = array();
    var 
$nbWords=0;
    var 
$title="";
    
    function 
SearchResult()
    {
    }
 
    function 
setUrl($URL)
    {
    
$this->url = preg_replace("#^/#","",$URL);
    }

    function 
addWord($word, $nbOccurences, $extract)
    {
    if (
strpos($word, " ") !== false)
    {
        
$word = "%22".$word."%22";
    }

    
$this->words[$this->nbWords] = stripslashes($word);
    
$this->wordsResult[$this->nbWords] = array($nbOccurences, $extract);
    
$this->nbWords++;
    }

    function 
format()
    {
    
$highlight = implode("+", $this->words);

        
$result = " <li>\n  <a href=\"/".$this->url."\">".getTitle($this->url)."</a>\n  <dl>\n";
    for (
$i = 0; $i < $this->nbWords; $i++)
    {
        
$result .= "   <dt><strong>".str_replace("%22",'"',$this->words[$i])."</strong> : ".$this->wordsResult[$i][0]." occurence".(($this->wordsResult[$i][0] > 1) ? "s" : "");
        
$result .= "   </dt>\n   <dd>\n".$this->wordsResult[$i][1]."\n   </dd>\n";
    }
        
$result .= "  </dl>\n </li>\n";
    return 
$result;
    }
}

function 
searchInSite($words, $caseSensitive = false)
{
    
$filesArray = array();
    
    
$source_dir = dir(".");
    while (
$filename = $source_dir->read())
    {
      if ((
ereg("\.php$",$filename)) && !(ereg(IGNORED_FILES,$filename)))
      {
        
array_push($filesArray, $filename);
      }
    }
    
$source_dir->close();
    
$lessons_dir = dir('./'.LESSONS_DIR);
    while (
$filename = $lessons_dir->read())
    {
      if ((
ereg("\.php$",$filename)) && !(ereg(IGNORED_FILES,$filename)))
      {
        
array_push($filesArray, LESSONS_DIR.'/'.$filename);
      }
    }
    
$lessons_dir->close();
    
    
array_push($filesArray, "cpcmozbar/index.php");
    
array_push($filesArray, "cpcmozbar/doc.php");
    
array_push($filesArray, "cpcmozbar/install.php");
    
array_push($filesArray, "forums/aide.php");
    
array_push($filesArray, "forums/guide.php");

    
$resultList = array();
    while (list(
$index,$filename) = each($filesArray))
    {
        
$textContent = getTextContent($filename);
        
$result = new SearchResult();
        
$score = 0;
        
reset($words);
        if (isset(
$_GET['type']) && ($_GET['type'] == "AND"))
        {
            
$match = true;
            while (list(
$index, $word) = each($words))
            {
                
$nbOccurences = countOccurences($textContent, $word, $extract, $caseSensitive);
                if (
$nbOccurences == 0)
                {
                    
$match = false;
                    break;
                }
                else
                {
                    
$result->addWord($word, $nbOccurences, $extract);
                    
$score += $nbOccurences;
                }
            }
        }
        else
        {
            
$match = false;
            while (list(
$index, $word) = each($words))
            {
                
$nbOccurences = countOccurences($textContent, $word, $extract, $caseSensitive);
                if (
$nbOccurences != 0)
                {
                    
$match = true;
                    
$result->addWord($word, $nbOccurences, $extract);
                    
$score += $nbOccurences;
                }
            }
        }

        if (
$match == true)
        {
           
$result->setUrl($filename);
           if (isset(
$resultList[$score]))
           {
             
$resultList[$score] .= $result->format();
           }
           else
           {
             
$resultList[$score] = $result->format();
           }
        }
    }

    
krsort($resultList);
    return 
$resultList;
}

?>