<?php

/*

Copyright © 2001 Nick Gammon.

  Author: Nick Gammon <nick@gammon.com.au>
  Web:    http://www.gammon.com.au/
  Date:   February 2001

  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. 

  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. 
  See the GNU General Public License for more details. 

  You should have received a copy of the GNU General Public License 
  along with this program; if not, write to 

  The Free Software Foundation, Inc., 
  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.


  The Free Software Foundation maintains a web page at: http://www.fsf.org

  See the file gpl.txt for the full GNU General Public License.

*/

require ("config.php");
require ($CONFIG_PATH . "general_config.php");
require ($INCLUDE_DIRECTORY . "common.php");

Init ("Forum search", "forum, search"); 

$forum_name = $control ['forum_name'];

function ShowForm ()
  {
  global $PHP_SELF, $searchfor, $bbtopic_id, $bbpost_id, $foruminfo;
  
 ?>
<hr>
<h3>Search for words</h3>

<p>Enter one or more words in the box below to find messages that match.</p>

<form METHOD="get" ACTION="<?php echo $PHP_SELF;?>"> 
<p>Search for: &nbsp;&nbsp; <input type=text name=searchfor 
   value="<?php echo stripslashes ($searchfor); ?>" size=50 maxlength=55>
</p>

<p>Look in  topic: &nbsp; <select name=bbtopic_id size=1>

<?php

  $result = mysql_query ("SELECT bbtopic.bbtopic_id, "
                       . "  concat(section_name, ': ', topic_name) "
                       . "AS description "
                       . "FROM bbtopic, bbsection "
                       . "WHERE bbsection.bbsection_id = bbtopic.bbsection_id  "
                       . "  AND bbtopic.bbtopic_id > 0  "
                       . "ORDER BY section_name, topic_name") 
    or Problem ("Select of topics failed: " . mysql_error ());
    
  echo "<option value=0 selected>(All topics)\n";
    
  while ($row = mysql_fetch_array ($result))
    {
    $id = $row ['bbtopic_id'];
    $desc = $row ['description'];
    if ($id == $bbtopic_id)
      $selected = 'selected';
    else
      $selected = '';
      
    echo "<option value=\"$id\" $selected>$desc\n";
    } // end of doing each row
  
  mysql_free_result ($result);
?>
</select>
</p>
<p><input Type=submit Value="Search"> </p>
<input type=hidden name=action value=search>
<?php  FormSession (); ?>

</form>

<?php

// admins can search for posts following a particular one
if ($foruminfo ['admin'])
  {
 ?>
 <hr>
<h3>Search for recent posts</h3>

<p>Enter the first post number that you want to see threads for.</p>

<form METHOD="get" ACTION="<?php echo $PHP_SELF;?>"> 
<p>Search for: &nbsp;&nbsp; <input type=text name=bbpost_id 
   value="<?php echo $bbpost_id; ?>" size=10 maxlength=10>
</p>
<p><input Type=submit Value="Show"> </p>
<input type=hidden name=action value=showrecent>
<?php  FormSession (); ?>

</form>

<?php
  	
  	
  }	// end of admin
  
  }   // end of ShowForm

function ShowRecentPosts ()
  {
  global $PHP_SELF, $searchfor, $bbpost_id, $foruminfo, $control;

  if ($bbpost_id <= 0)
    Problem ("Message ID not specified or negative");
    
  // show search results
  
  $datetimeformat = $control ['datetimeformat'];
  $tz = $foruminfo ['time_zone'];
  if (!$tz)
    $tz = 0;  // not logged in? Assume UTC
    
  $LIMIT = 500;
    
  $query = "SELECT bbsubject.bbsubject_id, "
         . "  CONCAT(section_name, ': ', topic_name) AS section_topic_name, "
         . "subject_name, "
         . "DATE_FORMAT(DATE_ADD(post_date, INTERVAL $tz HOUR), '$datetimeformat') AS thedate "
         . "FROM bbpost, bbsubject, bbtopic, bbsection "
         . "WHERE (bbpost_id >= $bbpost_id)  "
         . "      AND bbsection.bbsection_id = bbtopic.bbsection_id  "
         . "      AND bbtopic.bbtopic_id = bbsubject.bbtopic_id "
         . "      AND bbsubject.bbsubject_id = bbpost.bbsubject_id "
         . "GROUP BY bbsubject_id "
         . "ORDER BY section_name, topic_name, post_date DESC, subject_name  "
         . "LIMIT $LIMIT";
  
  
  // echo $query . "<br>";
  
  echo "<hr><h4>Recent posts listing (since message $bbpost_id)</h4>\n";
  
  $result = mysql_query ($query) 
    or Problem ("Select of messages failed: " . mysql_error ());

  $old_section_topic_name = "";
    
  while ($row = mysql_fetch_array ($result))
   {
   
   if ($row ['section_topic_name'] != $old_section_topic_name)
     {
    if ($old_section_topic_name != "")
      eList ();
     echo "<p><b>" . htmlspecialchars ($row ['section_topic_name']) . "</b></p>\n";
      
     $old_section_topic_name = $row ['section_topic_name'];
     bList ();
     }
    
   LI ();
   
   hLink (htmlspecialchars ($row ['subject_name']),
          "bbshowpost.php",
          "bbsubject_id=" . $row['bbsubject_id'],
          true);
   
   bList ();
   echo "<font size=1>" . htmlspecialchars($row ['thedate']) . "</font>\n";
   
   eList ();      
   } // end of while
  
  if ($old_section_topic_name != "")
    eList ();
             
  $count = mysql_num_rows ($result);
    
  if ($count >= $LIMIT)
    {
    echo "<p>Search limited to $count items.</p>\n";
  }
  else
  if ($count <= 0)
    echo "<p><b>No messages.</b></p>\n";

  echo "<p>(Sorted into section/topic order, then the most recent posts first.)</p>\n";
  mysql_free_result ($result);
  	  
  MessageTail ();
  die ();	
 	}
 	

// ---------------- start of main section -------------------

// DEBUG

// DebugVars ();

// validate input so we don't get sneaky SQL problems

CheckField ("topic", $bbtopic_id);
   
echo "<h1>Search the forum</h1><h2>" . htmlentities ($forum_name) . "</h2>\n";
 
CheckField ("message", $bbpost_id);
  
ShowForm ();    
 
if ($action == 'showrecent' && $foruminfo ['admin'])
  ShowRecentPosts ();
   
if ($action == 'search')
  {   
    
  // don't let them slip in semicolons, like ; drop database xxx; 
  $searchfor = str_replace (";", " ", $searchfor);
  
  $searchfor = trim ($searchfor); // get rid of spaces
  
  // don't let them use % or _ in the string
  $searchforfixed = addcslashes ($searchfor, "%_");            

  $searcharray = explode (" ", $searchforfixed);
  $searchstring = "";
  $not = "";
  $and_or = "AND";
  
  while (list ($key, $value) = each ($searcharray))
    {
    $value = trim ($value);
          
    if (empty ($value))
      continue;
        
    if (strtolower ($value) == "not")
      {
      $not = "NOT";
      continue;
      }

    if (strtolower ($value) == "and")
      {
      $and_or = "AND";
      continue;
      }

    if (strtolower ($value) == "or")
      {
      $and_or = "OR";
      continue;
      }
        
    if (!empty ($searchstring))
      $searchstring .= " $and_or ";
          
    $searchstring .= "$not (post_text LIKE '%$value%' OR "
                   . "subject_name LIKE '%$value%')";   
      
    $not = "";
      
    }
    
  if (strlen ($searchstring) == 0)
    ShowError ("You must specify something to search for");
  else
    {
    // show search results
    
    $datetimeformat = $control ['datetimeformat'];
    $tz = $foruminfo ['time_zone'];
    if (!$tz)
      $tz = 0;  // not logged in? Assume UTC
    
      
    $LIMIT = 50;
    
    if ($bbtopic_id > 0)
      $topic_where = "AND bbtopic.bbtopic_id = $bbtopic_id ";
    
    $query = "SELECT bbsubject.bbsubject_id, "
           . "  CONCAT(section_name, ': ', topic_name) AS section_topic_name, "
           . "subject_name, "
           . "DATE_FORMAT(DATE_ADD(post_date, INTERVAL $tz HOUR), '$datetimeformat') AS thedate "
           . "FROM bbpost, bbsubject, bbtopic, bbsection "
           . "WHERE ($searchstring)  "
           . $topic_where
           . "      AND bbsection.bbsection_id = bbtopic.bbsection_id  "
           . "      AND bbtopic.bbtopic_id = bbsubject.bbtopic_id "
           . "      AND bbsubject.bbsubject_id = bbpost.bbsubject_id "
           . "GROUP BY bbsubject_id "
           . "ORDER BY section_name, topic_name, post_date DESC, subject_name  "
           . "LIMIT $LIMIT";
    
    
    // echo $query . "<br>";
    
    echo "<hr><h4>Search results</h4>\n";
    
    $result = mysql_query ($query) 
      or Problem ("Select of messages failed: " . mysql_error ());

    $old_section_topic_name = "";
      
    while ($row = mysql_fetch_array ($result))
     {
     
     if ($row ['section_topic_name'] != $old_section_topic_name)
       {
      if ($old_section_topic_name != "")
        eList ();
       echo "<p><b>" . htmlspecialchars ($row ['section_topic_name']) . "</b></p>\n";
        
       $old_section_topic_name = $row ['section_topic_name'];
       bList ();
       }
      
     LI ();
     
     hLink (htmlspecialchars ($row ['subject_name']),
            "bbshowpost.php",
            "bbsubject_id=" . $row['bbsubject_id']);
     
     bList ();
     echo "<font size=1>" . htmlspecialchars($row ['thedate']) . "</font>\n";
     
     eList ();      
     } // end of while
    
    if ($old_section_topic_name != "")
      eList ();
               
    $count = mysql_num_rows ($result);
      
    if ($count >= $LIMIT)
      {
      echo "<p>Search limited to $count items.</p>\n";
      echo "<p>You can lower the number of matches by:</p>\n";
      bList ();
      LI (); echo "Searching in only one topic\n";
      LI (); echo "Adding more words to the 'search for' field\n";
      eList ();
    }
    else
    if ($count <= 0)
      echo "<p><b>No matches.</b></p>\n";

    echo "<p>(Sorted into section/topic order, then the most recent posts first.)</p>\n";
    mysql_free_result ($result);
        
    }   // end of something to search for
  } // end of search button pressed
  
echo "<hr>\n";

?>

<h3>Search hints
</h3>

<p>
You can search for:
</p>

<ul>
  <li><b>Multiple words</b> - all must appear in the post, not necessarily in the order specified.
<p>
eg. &quot;dog cat fish&quot; searches for posts with all three words somewhere in them
</p>
<p>
You can also use the word <b>AND</b> if you like. eg.  &quot;dog AND cat AND fish&quot;
</p>
  <li><b>Exclude a word</b> - put <b>NOT</b> in front of it.
<p>
eg. &quot;dog NOT cat&quot; searches for posts with &quot;dog&quot; in them but not &quot;cat&quot;
</p>
  <li><b>One word or another</b> - use the word <b>OR</b> to specify this
<p>
eg. &quot;dog OR cat fish spoon&quot; will search for &quot;dog&quot; or &quot;cat&quot; or &quot;fish&quot; or &quot;spoon&quot;
</p>
<li><b>Combinations</b> - combine the above for more complex queries
<p>
eg. &quot;dog and cat or fish and not fruit&quot;
</p>
</ul>

<p>Both the text of the post, and the subject line, are searched.</p>

<hr>

<?php  
hLink ("Back to " . htmlentities ($forum_name), "bbshowpost.php");
        
?>

<hr>

<?php MessageTail (); ?>
