search
[ class tree: search ] [ index: search ] [ all elements ]

Source for file search.inc.php

Documentation is available at search.inc.php

  1. <?php
  2.     /**
  3.      * @author            Matthias Reuter ($LastChangedBy: matthias $)
  4.      * @version            $LastChangedDate: 2008-10-31 23:53:28 +0000 (Fr, 31 Okt 2008) $
  5.      * @package            search
  6.      * @copyright        2007-2010 IPBWI development team
  7.      * @link            http://ipbwi.com
  8.      * @since            2.0
  9.      * @license            http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License
  10.      */
  11.     class ipbwi_search extends ipbwi {
  12.         private $ipbwi            null;
  13.         /**
  14.          * @desc            Loads and checks different vars when class is initiating
  15.          * @author            Matthias Reuter
  16.          * @since            2.0
  17.          * @ignore
  18.          */
  19.         public function __construct($ipbwi){
  20.             // loads common classes
  21.             $this->ipbwi $ipbwi;
  22.         }
  23.         /**
  24.          * @desc            Returns the search results of a search.
  25.          * @param    int        $searchID ID of the Search
  26.          * @return    array    Search Results or false on failure. BBCode is stripped off the results. To hilight the search string use str_replace() in your main script.
  27.          * @author            Matthias Reuter
  28.          * @sample
  29.          *  <code>
  30.          *  $searchID = $ipbwi->search->simple('search string');
  31.          *  $ipbwi->search->results($searchID);
  32.          *  </code>
  33.          * @since            2.0
  34.          */
  35.         public function results($searchID){
  36.             // Select the correct/current search from the database
  37.             $this->ipbwi->ips_wrapper->DB->query('SELECT * FROM '.$this->ipbwi->board['sql_tbl_prefix'].'search_results WHERE id="'.$searchID.'"');
  38.             if($row $this->ipbwi->ips_wrapper->DB->fetch()){
  39.                 $searchinfo $row;
  40.                 $tomato stripslashes($row['query_cache']);
  41.                 $this->ipbwi->ips_wrapper->DB->query($tomato);
  42.                 $results array();
  43.                 while($row $this->ipbwi->ips_wrapper->DB->fetch()){
  44.                     // make proper XHTML
  45.                     $row['post']                $this->ipbwi->ips_wrapper->parser->pre_display_parse($row['post']);
  46.                     $row['post']                $this->ipbwi->properXHTML($row['post']);
  47.                     $row['title']                $this->ipbwi->properXHTML($row['title']);
  48.                     $row['author_name']            $this->ipbwi->properXHTML($row['author_name']);
  49.                     $results[$row;
  50.                 }
  51.                 $searchinfo['results'$results;
  52.                 return $searchinfo;
  53.             }
  54.             $this->ipbwi->addSystemMessage('Error',$this->ipbwi->getLibLang('searchIDnotExist'),'Located in file <strong>'.__FILE__.'</strong> at class <strong>'.__CLASS__.'</strong> in function <strong>'.__FUNCTION__.'</strong> on line #<strong>'.__LINE__.'</strong>');
  55.             return false;
  56.         }
  57.         /**
  58.          * @desc            Performs a simple search and returns a search id.
  59.          * @param    string    $string Text to search for (SQL rules apply)
  60.          * @param    string    $forums Default: '*' (any), or comma-separated list of forum IDs
  61.          * @param    bool    $dateorder Default: false, true = Order by post_date
  62.          * @param    bool    $recursive Default: false, true = Get subforums, too
  63.          * @return    string    Search ID or false on failure
  64.          * @author            Matthias Reuter
  65.          * @sample
  66.          *  <code>
  67.          *  $ipbwi->search->simple('search string');
  68.          *  </code>
  69.          * @since            2.0
  70.          */
  71.         public function simple($string$forums '*'$dateorder false$recursive false){
  72.             $string trim($string);
  73.             // get all subforum ids
  74.             if($recursive == && is_array($forums)){
  75.                 // make proper array for get_all_subforums function
  76.                 foreach($forums as $get_sub){
  77.                     $get_sub_forums[]['id'$get_sub;
  78.                 }
  79.                 $forums array()// reset array
  80.                 // revert array-syntax after getting all subforums
  81.                 foreach($this->ipbwi->forum->getAllSubs($get_sub_forums,'array_ids_only'as $forum){
  82.                     $forums[$forum['id'];
  83.                 }
  84.             }
  85.             // Lets get all the IDs of readable topics and create a comma-separated string from them
  86.             // Use the handy list_forum_topics function to create a multi-dimensional array of all readable topics in the given forums (or all forums if none specified)...
  87.             // I figured no forum will ever have more than 100000 topics :D
  88.             $multiarray $this->ipbwi->topic->getList($forums,array('orderby' => 'tid''limit' => 100000));
  89.             // For each topic, grab it's ID and add it to the topics string (with a comma of course)
  90.             if(is_array($multiarray&& count($multiarray0){
  91.                 foreach($multiarray as $topic){
  92.                     $topics[$topic['tid'];
  93.                 }
  94.                 $topics implode(',',$topics);
  95.             }
  96.             // Make sure we have a list of topics to search in (presumable greater than 2 chars :D)
  97.             if(strlen($topics2){
  98.                 // Hmmm something went wrong, so lets output a friendly-ish error message
  99.                 $this->ipbwi->addSystemMessage('Error',$this->ipbwi->getLibLang('searchNoResults'),'Located in file <strong>'.__FILE__.'</strong> at class <strong>'.__CLASS__.'</strong> in function <strong>'.__FUNCTION__.'</strong> on line #<strong>'.__LINE__.'</strong>');
  100.                 return false;
  101.             }
  102.             // Only work out readable forums if we haven't been given a list of forums to read
  103.             if($forums '*'){
  104.                 // Get rid of the '*' :D
  105.                 $forums '';
  106.                 // Lets get all the IDs of readable forums and create a comma-separated string from them
  107.                 // Use the handy get_member_readable_forums function to create a mulit-dimensional array of all readable forums
  108.                 $multiarray $this->ipbwi->forum->getReadable();
  109.                 // For each forum, grab it's ID and add it to the topics string (with a comma of course)
  110.                 if(is_array($multiarray&& count($multiarray0){
  111.                     foreach($multiarray as $forum){
  112.                         $forums[$forum['id'];
  113.                     }
  114.                     $forums implode(',',$forums);
  115.                 }
  116.                 // Make sure we have a list of forums to search in
  117.                 if(!$forums){
  118.                     // Hmmm something went wrong, so lets output a friendly-ish error message
  119.                     $this->ipbwi->addSystemMessage('Error',$this->ipbwi->getLibLang('searchNoResults'),'Located in file <strong>'.__FILE__.'</strong> at class <strong>'.__CLASS__.'</strong> in function <strong>'.__FUNCTION__.'</strong> on line #<strong>'.__LINE__.'</strong>');
  120.                     return false;
  121.                 }
  122.             }else{
  123.                 if(is_array($forums)){
  124.                     $forums implode(',',$forums);
  125.                 }
  126.             }
  127.             // Weird thing - MySQL versions greater than 40010 make this function buggy unless we remove certain characters
  128.             // Get (eventually!) the MySQL version
  129.             $this->ipbwi->ips_wrapper->DB->query('SELECT VERSION() AS version');
  130.             if(!$row $this->ipbwi->ips_wrapper->DB->fetch()){
  131.                 $this->ipbwi->ips_wrapper->DB->query('SHOW VARIABLES LIKE "version"');
  132.                 $row $this->ipbwi->ips_wrapper->DB->fetch();
  133.             }
  134.             $version explode('.'preg_replace('/^(.+?)[-_]?/''\\1'$row['version']));
  135.             $version['0'(!isset($versionOR !isset($version['0'])) '3' $version['0'];
  136.             $version['1'(!isset($version['1'])) '21' $version['1'];
  137.             $version['2'(!isset($version['2'])) '0' $version['2'];
  138.             $version intval(sprintf('%d%02d%02d'$version['0']$version['1']intval($version['2'])));
  139.             // We now have the mysql version in an int for later use.
  140.             if($version >= '40010'){
  141.                 // Remove stuff we cant have
  142.                 $string str_replace(array('|''&quot;''&gt;''%')array('|''\'''>''')trim($string));
  143.             }else{
  144.                 $string str_replace(array('%''_''|')array('\\%''\\_''|')trim(strtolower($string)));
  145.                 $string preg_replace('/\s+(and|or)$/' '' $string);
  146.             }
  147.             // Complicated MySQL query =] Basically this counts how many times the search string is found within any topic in any of the readable forums...
  148.             // Oh, and if the MySQL version is greater than 40010 we have to add "IN BOOLEAN MODE" for complicated MySQL reasons :D
  149.             $this->ipbwi->ips_wrapper->DB->query('SELECT COUNT(*) as count FROM '.$this->ipbwi->board['sql_tbl_prefix'].'posts p WHERE p.topic_id IN ('.$topics.') AND MATCH(post) AGAINST ("'.$string.'" '.(($version >= '40010''IN BOOLEAN MODE' '').')');
  150.             $row $this->ipbwi->ips_wrapper->DB->fetch();
  151.             // MySQL counted 0 matches of the search string - it isn't there...
  152.             if($row['count''1'){
  153.                 // No results, so lets output a friendly error message
  154.                 $this->ipbwi->addSystemMessage('Error',$this->ipbwi->getLibLang('searchNoResults'),'Located in file <strong>'.__FILE__.'</strong> at class <strong>'.__CLASS__.'</strong> in function <strong>'.__FUNCTION__.'</strong> on line #<strong>'.__LINE__.'</strong>');
  155.                 return false;
  156.             }
  157.             // Ok, so we found at least one match... Lets build another complicated MySQL query to store in the database for the search_results function to query.
  158.             $store 'SELECT MATCH(post) AGAINST ("'.$string.'" '.(($version >= '40010''IN BOOLEAN MODE' '').') as score, t.approved, t.tid, t.posts AS topic_posts, t.title AS topic_title, t.views, t.forum_id, p.post, p.author_id, p.author_name, p.post_date, p.queued, p.pid, p.post_htmlstate, m. * , me. * , pp. * FROM '.$this->ipbwi->board['sql_tbl_prefix'].'posts p LEFT JOIN '.$this->ipbwi->board['sql_tbl_prefix'].'topics t ON ( p.topic_id = t.tid ) LEFT JOIN '.$this->ipbwi->board['sql_tbl_prefix'].'members m ON ( m.id = p.author_id ) LEFT JOIN '.$this->ipbwi->board['sql_tbl_prefix'].'member_extra me ON ( me.id = p.author_id ) LEFT JOIN '.$this->ipbwi->board['sql_tbl_prefix'].'profile_portal pp ON ( pp.pp_member_id = p.author_id ) WHERE t.forum_id IN ('.$forums.') AND t.tid IN ('.$topics.') AND t.title IS NOT NULL AND p.queued IN ( 0, 1 )  AND MATCH(post) AGAINST ("'.$string.'" '.(($version >= '40010''IN BOOLEAN MODE' '').')';
  159.             // Date order?
  160.             if($dateorder){
  161.                 $store .= ' ORDER BY p.post_date DESC';
  162.             }
  163.             // Generate a unique search id
  164.             $searchid md5(uniqid(microtime()1));
  165.             // Insert it into the database
  166.             // "it" being the search ID we just generated, the current date (timestamp), two topic things which I haven't worked out the point of (yet),
  167.             // the ID of the logged in member who did the search, their current IP address, a pointless nothing, and obviously, finally, the search results MySQL query...
  168.             $this->ipbwi->ips_wrapper->DB->query('INSERT INTO '.$this->ipbwi->board['sql_tbl_prefix'].'search_results (id, search_date, topic_id, topic_max, member_id, ip_address, post_id, query_cache) VALUES("'.$searchid.'", "'.time().'", "'.$topics.'", "'.$row['count'].'", "'.$this->ipbwi->member->myInfo['member_id'].'", "'.$this->ipbwi->ips_wrapper->input['IP_ADDRESS'].'", NULL, "'.addslashes($store).'")');
  169.             // Return the unique search id.
  170.             return $searchid;
  171.         }
  172.     }
  173. ?>

Documentation generated on Sat, 23 Oct 2010 23:36:11 +0200 by phpDocumentor 1.4.3