home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 April / PCWorld_2005-04_cd.bin / akce / web / unitednuke / unitednuke.exe / html / includes / functions_search.php < prev    next >
PHP Script  |  2004-01-10  |  24KB  |  531 lines

  1. <?php
  2. /***************************************************************************
  3. *                              functions_search.php
  4. *                              -------------------
  5. *     begin                : Wed Sep 05 2001
  6. *     copyright            : (C) 2002 The phpBB Group
  7. *     email                : support@phpbb.com
  8. *
  9. *     $Id: functions_search.php,v 1.8.2.14 2003/05/03 23:24:02 acydburn Exp $
  10. *
  11. ****************************************************************************/
  12. /***************************************************************************
  13. * phpbb2 forums port version 2.0.5 (c) 2003 - Nuke Cops (http://nukecops.com)
  14. *
  15. * Ported by Nuke Cops to phpbb2 standalone 2.0.5 Test
  16. * and debugging completed by the Elite Nukers and site members.
  17. *
  18. * You run this package at your sole risk. Nuke Cops and affiliates cannot
  19. * be held liable if anything goes wrong. You are advised to test this
  20. * package on a development system. Backup everything before implementing
  21. * in a production environment. If something goes wrong, you can always
  22. * backout and restore your backups.
  23. *
  24. * Installing and running this also means you agree to the terms of the AUP
  25. * found at Nuke Cops.
  26. *
  27. * This is version 2.0.5 of the phpbb2 forum port for PHP-Nuke. Work is based
  28. * on Tom Nitzschner's forum port version 2.0.6. Tom's 2.0.6 port was based
  29. * on the phpbb2 standalone version 2.0.3. Our version 2.0.5 from Nuke Cops is
  30. * now reflecting phpbb2 standalone 2.0.5 that fixes some bugs and the
  31. * invalid_session error message.
  32. ***************************************************************************/
  33. /***************************************************************************
  34.  *   This file is part of the phpBB2 port to Nuke 6.0 (c) copyright 2002
  35.  *   by Tom Nitzschner (tom@toms-home.com)
  36.  *   http://bbtonuke.sourceforge.net (or http://www.toms-home.com)
  37.  *
  38.  *   As always, make a backup before messing with anything. All code
  39.  *   release by me is considered sample code only. It may be fully
  40.  *   functual, but you use it at your own risk, if you break it,
  41.  *   you get to fix it too. No waranty is given or implied.
  42.  *
  43.  *   Please post all questions/request about this port on http://bbtonuke.sourceforge.net first,
  44.  *   then on my site. All original header code and copyright messages will be maintained
  45.  *   to give credit where credit is due. If you modify this, the only requirement is
  46.  *   that you also maintain all original copyright messages. All my work is released
  47.  *   under the GNU GENERAL PUBLIC LICENSE. Please see the README for more information.
  48.  *
  49.  ***************************************************************************/
  50. /***************************************************************************
  51.  *
  52.  *   This program is free software; you can redistribute it and/or modify
  53.  *   it under the terms of the GNU General Public License as published by
  54.  *   the Free Software Foundation; either version 2 of the License, or
  55.  *   (at your option) any later version.
  56.  *
  57.  ***************************************************************************/
  58.  
  59. function clean_words($mode, &$entry, &$stopword_list, &$synonym_list)
  60. {
  61.         static $drop_char_match =   array('^', '$', '&', '(', ')', '<', '>', '`', '\'', '"', '|', ',', '@', '_', '?', '%', '-', '~', '+', '.', '[', ']', '{', '}', ':', '\\', '/', '=', '#', '\'', ';', '!');
  62.         static $drop_char_replace = array(' ', ' ', ' ', ' ', ' ', ' ', ' ', '',  '',   ' ', ' ', ' ', ' ', '',  ' ', ' ', '',  ' ',  ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' , ' ', ' ', ' ', ' ',  ' ', ' ');
  63.  
  64.         $entry = ' ' . strip_tags(strtolower($entry)) . ' ';
  65.  
  66.         if ( $mode == 'post' )
  67.         {
  68.                 // Replace line endings by a space
  69.                 $entry = preg_replace('/[\n\r]/is', ' ', $entry);
  70.                 // HTML entities like  
  71.                 $entry = preg_replace('/\b&[a-z]+;\b/', ' ', $entry);
  72.                 // Remove URL's
  73.                 $entry = preg_replace('/\b[a-z0-9]+:\/\/[a-z0-9\.\-]+(\/[a-z0-9\?\.%_\-\+=&\/]+)?/', ' ', $entry);
  74.                 // Quickly remove BBcode.
  75.                 $entry = preg_replace('/\[img:[a-z0-9]{10,}\].*?\[\/img:[a-z0-9]{10,}\]/', ' ', $entry);
  76.                 $entry = preg_replace('/\[\/?url(=.*?)?\]/', ' ', $entry);
  77.                 $entry = preg_replace('/\[\/?[a-z\*=\+\-]+(\:?[0-9a-z]+)?:[a-z0-9]{10,}(\:[a-z0-9]+)?=?.*?\]/', ' ', $entry);
  78.         }
  79.         else if ( $mode == 'search' )
  80.         {
  81.                 $entry = str_replace(' +', ' and ', $entry);
  82.                 $entry = str_replace(' -', ' not ', $entry);
  83.         }
  84.  
  85.         //
  86.         // Filter out strange characters like ^, $, &, change "it's" to "its"
  87.         //
  88.         for($i = 0; $i < count($drop_char_match); $i++)
  89.         {
  90.                 $entry =  str_replace($drop_char_match[$i], $drop_char_replace[$i], $entry);
  91.         }
  92.  
  93.         if ( $mode == 'post' )
  94.         {
  95.                 $entry = str_replace('*', ' ', $entry);
  96.  
  97.                 // 'words' that consist of <3 or >20 characters are removed.
  98.         $entry = preg_replace('/[ ]([\S]{1,2}|[\S]{21,})[ ]/',' ', $entry);
  99.         }
  100.  
  101.         if ( !empty($stopword_list) )
  102.         {
  103.                 for ($j = 0; $j < count($stopword_list); $j++)
  104.                 {
  105.                         $stopword = trim($stopword_list[$j]);
  106.  
  107.                         if ( $mode == 'post' || ( $stopword != 'not' && $stopword != 'and' && $stopword != 'or' ) )
  108.                         {
  109.                                 $entry = str_replace(' ' . trim($stopword) . ' ', ' ', $entry);
  110.                         }
  111.                 }
  112.         }
  113.  
  114.         if ( !empty($synonym_list) )
  115.         {
  116.                 for ($j = 0; $j < count($synonym_list); $j++)
  117.                 {
  118.                         list($replace_synonym, $match_synonym) = split(' ', trim(strtolower($synonym_list[$j])));
  119.                         if ( $mode == 'post' || ( $match_synonym != 'not' && $match_synonym != 'and' && $match_synonym != 'or' ) )
  120.                         {
  121.                                 $entry =  str_replace(' ' . trim($match_synonym) . ' ', ' ' . trim($replace_synonym) . ' ', $entry);
  122.                         }
  123.                 }
  124.         }
  125.  
  126.         return $entry;
  127. }
  128.  
  129. function split_words(&$entry, $mode = 'post')
  130. {
  131.         // If you experience problems with the new method, uncomment this block.
  132. /*
  133.         $rex = ( $mode == 'post' ) ? "/\b([\w▒╡- ][\w▒╡- ']*[\w▒╡- ]+|[\w▒╡- ]+?)\b/" : '/(\*?[a-z0-9▒╡- ]+\*?)|\b([a-z0-9▒╡- ]+)\b/';
  134.         preg_match_all($rex, $entry, $split_entries);
  135.  
  136.         return $split_entries[1];
  137. */
  138.     // Trim 1+ spaces to one space and split this trimmed string into words.
  139.     return explode(' ', trim(preg_replace('#\s+#', ' ', $entry)));
  140. }
  141.  
  142. function add_search_words($mode, $post_id, $post_text, $post_title = '')
  143. {
  144.         global $db, $phpbb_root_path, $board_config, $lang;
  145.  
  146.         $stopword_array = @file($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . "/search_stopwords.txt");
  147.         $synonym_array = @file($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . "/search_synonyms.txt");
  148.  
  149.         $search_raw_words = array();
  150.         $search_raw_words['text'] = split_words(clean_words('post', $post_text, $stopword_array, $synonym_array));
  151.         $search_raw_words['title'] = split_words(clean_words('post', $post_title, $stopword_array, $synonym_array));
  152.     @set_time_limit(0);
  153.         $word = array();
  154.         $word_insert_sql = array();
  155.         while ( list($word_in, $search_matches) = @each($search_raw_words) )
  156.         {
  157.                 $word_insert_sql[$word_in] = '';
  158.                 if ( !empty($search_matches) )
  159.                 {
  160.                         for ($i = 0; $i < count($search_matches); $i++)
  161.                         {
  162.                                 $search_matches[$i] = trim($search_matches[$i]);
  163.  
  164.                                 if( $search_matches[$i] != '' )
  165.                                 {
  166.                                         $word[] = $search_matches[$i];
  167.                                         if ( !strstr($word_insert_sql[$word_in], "'" . $search_matches[$i] . "'") )
  168.                                         {
  169.                                                 $word_insert_sql[$word_in] .= ( $word_insert_sql[$word_in] != "" ) ? ", '" . $search_matches[$i] . "'" : "'" . $search_matches[$i] . "'";
  170.                                         }
  171.                                 }
  172.                         }
  173.                 }
  174.         }
  175.  
  176.         if ( count($word) )
  177.         {
  178.                 sort($word);
  179.  
  180.                 $prev_word = '';
  181.                 $word_text_sql = '';
  182.                 $temp_word = array();
  183.                 for($i = 0; $i < count($word); $i++)
  184.                 {
  185.                         if ( $word[$i] != $prev_word )
  186.                         {
  187.                                 $temp_word[] = $word[$i];
  188.                                 $word_text_sql .= ( ( $word_text_sql != '' ) ? ', ' : '' ) . "'" . $word[$i] . "'";
  189.                         }
  190.                         $prev_word = $word[$i];
  191.                 }
  192.                 $word = $temp_word;
  193.  
  194.                 $check_words = array();
  195.                 switch( SQL_LAYER )
  196.                 {
  197.                         case 'postgresql':
  198.                         case 'msaccess':
  199.                         case 'mssql-odbc':
  200.                         case 'oracle':
  201.                         case 'db2':
  202.                                 $sql = "SELECT word_id, word_text
  203.                                         FROM " . SEARCH_WORD_TABLE . "
  204.                                         WHERE word_text IN ($word_text_sql)";
  205.                                 if ( !($result = $db->sql_query($sql)) )
  206.                                 {
  207.                                         message_die(GENERAL_ERROR, 'Could not select words', '', __LINE__, __FILE__, $sql);
  208.                                 }
  209.  
  210.                                 while ( $row = $db->sql_fetchrow($result) )
  211.                                 {
  212.                                         $check_words[$row['word_text']] = $row['word_id'];
  213.                                 }
  214.                                 break;
  215.                 }
  216.  
  217.                 $value_sql = '';
  218.                 $match_word = array();
  219.                 for ($i = 0; $i < count($word); $i++)
  220.                 {
  221.                         $new_match = true;
  222.                         if ( isset($check_words[$word[$i]]) )
  223.                         {
  224.                                 $new_match = false;
  225.                         }
  226.  
  227.                         if ( $new_match )
  228.                         {
  229.                                 switch( SQL_LAYER )
  230.                                 {
  231.                                         case 'mysql':
  232.                                         case 'mysql4':
  233.                                                 $value_sql .= ( ( $value_sql != '' ) ? ', ' : '' ) . '(\'' . $word[$i] . '\', 0)';
  234.                                                 break;
  235.                                         case 'mssql':
  236.                                                 $value_sql .= ( ( $value_sql != '' ) ? ' UNION ALL ' : '' ) . "SELECT '" . $word[$i] . "', 0";
  237.                                                 break;
  238.                                         default:
  239.                                                 $sql = "INSERT INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)
  240.                                                         VALUES ('" . $word[$i] . "', 0)";
  241.                                                 if( !$db->sql_query($sql) )
  242.                                                 {
  243.                                                         message_die(GENERAL_ERROR, 'Could not insert new word', '', __LINE__, __FILE__, $sql);
  244.                                                 }
  245.                                                 break;
  246.                                 }
  247.                         }
  248.                 }
  249.  
  250.                 if ( $value_sql != '' )
  251.                 {
  252.                         switch ( SQL_LAYER )
  253.                         {
  254.                                 case 'mysql':
  255.                                 case 'mysql4':
  256.                                         $sql = "INSERT IGNORE INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)
  257.                                                 VALUES $value_sql";
  258.                                         break;
  259.                                 case 'mssql':
  260.                                         $sql = "INSERT INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)
  261.                                                 $value_sql";
  262.                                         break;
  263.                         }
  264.  
  265.                         if ( !$db->sql_query($sql) )
  266.                         {
  267.                                 message_die(GENERAL_ERROR, 'Could not insert new word', '', __LINE__, __FILE__, $sql);
  268.                         }
  269.                 }
  270.         }
  271.  
  272.         while( list($word_in, $match_sql) = @each($word_insert_sql) )
  273.         {
  274.                 $title_match = ( $word_in == 'title' ) ? 1 : 0;
  275.  
  276.                 if ( $match_sql != '' )
  277.                 {
  278.                         $sql = "INSERT IGNORE INTO " . SEARCH_MATCH_TABLE . " (post_id, word_id, title_match)
  279.                                 SELECT $post_id, word_id, $title_match
  280.                                         FROM " . SEARCH_WORD_TABLE . "
  281.                                         WHERE word_text IN ($match_sql)";
  282.                         if ( !$db->sql_query($sql) )
  283.                         {
  284.                                 message_die(GENERAL_ERROR, 'Could not insert new word matches', '', __LINE__, __FILE__, $sql);
  285.                         }
  286.                 }
  287.         }
  288.  
  289.         if ($mode == 'single')
  290.         {
  291.                 remove_common('single', 4/10, $word);
  292.         }
  293.  
  294.         return;
  295. }
  296.  
  297. //
  298. // Check if specified words are too common now
  299. //
  300. function remove_common($mode, $fraction, $word_id_list = array())
  301. {
  302.         global $db;
  303.  
  304.         $sql = "SELECT COUNT(post_id) AS total_posts
  305.                 FROM " . POSTS_TABLE;
  306.         if ( !($result = $db->sql_query($sql)) )
  307.         {
  308.                 message_die(GENERAL_ERROR, 'Could not obtain post count', '', __LINE__, __FILE__, $sql);
  309.         }
  310.  
  311.         $row = $db->sql_fetchrow($result);
  312.  
  313.         if ( $row['total_posts'] >= 100 )
  314.         {
  315.                 $common_threshold = floor($row['total_posts'] * $fraction);
  316.  
  317.                 if ( $mode == 'single' && count($word_id_list) )
  318.                 {
  319.                         $word_id_sql = '';
  320.                         for($i = 0; $i < count($word_id_list); $i++)
  321.                         {
  322.                                 $word_id_sql .= ( ( $word_id_sql != '' ) ? ', ' : '' ) . "'" . $word_id_list[$i] . "'";
  323.                         }
  324.  
  325.                         $sql = "SELECT m.word_id
  326.                                 FROM " . SEARCH_MATCH_TABLE . " m, " . SEARCH_WORD_TABLE . " w
  327.                                 WHERE w.word_text IN ($word_id_sql)
  328.                                         AND m.word_id = w.word_id
  329.                                 GROUP BY m.word_id
  330.                                 HAVING COUNT(m.word_id) > $common_threshold";
  331.                 }
  332.                 else
  333.                 {
  334.                         $sql = "SELECT word_id
  335.                                 FROM " . SEARCH_MATCH_TABLE . "
  336.                                 GROUP BY word_id
  337.                                 HAVING COUNT(word_id) > $common_threshold";
  338.                 }
  339.  
  340.                 if ( !($result = $db->sql_query($sql)) )
  341.                 {
  342.                         message_die(GENERAL_ERROR, 'Could not obtain common word list', '', __LINE__, __FILE__, $sql);
  343.                 }
  344.  
  345.                 $common_word_id = '';
  346.                 while ( $row = $db->sql_fetchrow($result) )
  347.                 {
  348.                         $common_word_id .= ( ( $common_word_id != '' ) ? ', ' : '' ) . $row['word_id'];
  349.                 }
  350.                 $db->sql_freeresult($result);
  351.  
  352.                 if ( $common_word_id != '' )
  353.                 {
  354.                         $sql = "UPDATE " . SEARCH_WORD_TABLE . "
  355.                                 SET word_common = " . TRUE . "
  356.                                 WHERE word_id IN ($common_word_id)";
  357.                         if ( !$db->sql_query($sql) )
  358.                         {
  359.                                 message_die(GENERAL_ERROR, 'Could not delete word list entry', '', __LINE__, __FILE__, $sql);
  360.                         }
  361.  
  362.                         $sql = "DELETE FROM " . SEARCH_MATCH_TABLE . "
  363.                                 WHERE word_id IN ($common_word_id)";
  364.                         if ( !$db->sql_query($sql) )
  365.                         {
  366.                                 message_die(GENERAL_ERROR, 'Could not delete word match entry', '', __LINE__, __FILE__, $sql);
  367.                         }
  368.                 }
  369.         }
  370.  
  371.         return;
  372. }
  373.  
  374. function remove_search_post($post_id_sql)
  375. {
  376.         global $db;
  377.  
  378.         $words_removed = false;
  379.  
  380.         switch ( SQL_LAYER )
  381.         {
  382.                 case 'mysql':
  383.                 case 'mysql4':
  384.                         $sql = "SELECT word_id
  385.                                 FROM " . SEARCH_MATCH_TABLE . "
  386.                                 WHERE post_id IN ($post_id_sql)
  387.                                 GROUP BY word_id";
  388.                         if ( $result = $db->sql_query($sql) )
  389.                         {
  390.                                 $word_id_sql = '';
  391.                                 while ( $row = $db->sql_fetchrow($result) )
  392.                                 {
  393.                                         $word_id_sql .= ( $word_id_sql != '' ) ? ', ' . $row['word_id'] : $row['word_id'];
  394.                                 }
  395.  
  396.                                 $sql = "SELECT word_id
  397.                                         FROM " . SEARCH_MATCH_TABLE . "
  398.                                         WHERE word_id IN ($word_id_sql)
  399.                                         GROUP BY word_id
  400.                                         HAVING COUNT(word_id) = 1";
  401.                                 if ( $result = $db->sql_query($sql) )
  402.                                 {
  403.                                         $word_id_sql = '';
  404.                                         while ( $row = $db->sql_fetchrow($result) )
  405.                                         {
  406.                                                 $word_id_sql .= ( $word_id_sql != '' ) ? ', ' . $row['word_id'] : $row['word_id'];
  407.                                         }
  408.  
  409.                                         if ( $word_id_sql != '' )
  410.                                         {
  411.                                                 $sql = "DELETE FROM " . SEARCH_WORD_TABLE . "
  412.                                                         WHERE word_id IN ($word_id_sql)";
  413.                                                 if ( !$db->sql_query($sql) )
  414.                                                 {
  415.                                                         message_die(GENERAL_ERROR, 'Could not delete word list entry', '', __LINE__, __FILE__, $sql);
  416.                                                 }
  417.  
  418.                                                 $words_removed = $db->sql_affectedrows();
  419.                                         }
  420.                                 }
  421.                         }
  422.                         break;
  423.  
  424.                 default:
  425.                         $sql = "DELETE FROM " . SEARCH_WORD_TABLE . "
  426.                                 WHERE word_id IN (
  427.                                         SELECT word_id
  428.                                         FROM " . SEARCH_MATCH_TABLE . "
  429.                                         WHERE word_id IN (
  430.                                                 SELECT word_id
  431.                                                 FROM " . SEARCH_MATCH_TABLE . "
  432.                                                 WHERE post_id IN ($post_id_sql)
  433.                                                 GROUP BY word_id
  434.                                         )
  435.                                         GROUP BY word_id
  436.                                         HAVING COUNT(word_id) = 1
  437.                                 )";
  438.                         if ( !$db->sql_query($sql) )
  439.                         {
  440.                                 message_die(GENERAL_ERROR, 'Could not delete old words from word table', '', __LINE__, __FILE__, $sql);
  441.                         }
  442.  
  443.                         $words_removed = $db->sql_affectedrows();
  444.  
  445.                         break;
  446.         }
  447.  
  448.         $sql = "DELETE FROM " . SEARCH_MATCH_TABLE . "
  449.                 WHERE post_id IN ($post_id_sql)";
  450.         if ( !$db->sql_query($sql) )
  451.         {
  452.                 message_die(GENERAL_ERROR, 'Error in deleting post', '', __LINE__, __FILE__, $sql);
  453.         }
  454.  
  455.         return $words_removed;
  456. }
  457.  
  458. //
  459. // Username search
  460. //
  461. function username_search($search_match)
  462. {
  463.         global $db, $board_config, $template, $lang, $images, $theme, $phpEx, $phpbb_root_path;
  464.         global $starttime, $gen_simple_header;
  465.  
  466.         $gen_simple_header = TRUE;
  467.  
  468.         $username_list = '';
  469.         if ( !empty($search_match) )
  470.         {
  471.                 $username_search = preg_replace('/\*/', '%', trim(strip_tags($search_match)));
  472.  
  473.                 $sql = "SELECT username
  474.                         FROM " . USERS_TABLE . "
  475.                         WHERE username LIKE '" . str_replace("\'", "''", $username_search) . "' AND user_id <> " . ANONYMOUS . "
  476.                         ORDER BY username";
  477.                 if ( !($result = $db->sql_query($sql)) )
  478.                 {
  479.                         message_die(GENERAL_ERROR, 'Could not obtain search results', '', __LINE__, __FILE__, $sql);
  480.                 }
  481.  
  482.                 if ( $row = $db->sql_fetchrow($result) )
  483.                 {
  484.                         do
  485.                         {
  486.                                 $username_list .= '<option value="' . $row['username'] . '">' . $row['username'] . '</option>';
  487.                         }
  488.                         while ( $row = $db->sql_fetchrow($result) );
  489.                 }
  490.                 else
  491.                 {
  492.                         $username_list .= '<option>' . $lang['No_match']. '</option>';
  493.                 }
  494.                 $db->sql_freeresult($result);
  495.         }
  496.  
  497.         $page_title = $lang['Search'];
  498.         include("includes/page_header_review.php");
  499.  
  500.         $template->set_filenames(array(
  501.                 'search_user_body' => 'search_username.tpl')
  502.         );
  503.  
  504.         $template->assign_vars(array(
  505.                 'USERNAME' => ( !empty($search_match) ) ? strip_tags($search_match) : '',
  506.  
  507.                 'L_CLOSE_WINDOW' => $lang['Close_window'],
  508.                 'L_SEARCH_USERNAME' => $lang['Find_username'],
  509.                 'L_UPDATE_USERNAME' => $lang['Select_username'],
  510.                 'L_SELECT' => $lang['Select'],
  511.                 'L_SEARCH' => $lang['Search'],
  512.                 'L_SEARCH_EXPLAIN' => $lang['Search_author_explain'],
  513.                 'L_CLOSE_WINDOW' => $lang['Close_window'],
  514.  
  515.                 'S_USERNAME_OPTIONS' => $username_list,
  516.                 'S_SEARCH_ACTION' => append_sid("search.$phpEx?mode=searchuser&popup=1"))
  517.         );
  518.  
  519.         if ( $username_list != '' )
  520.         {
  521.                 $template->assign_block_vars('switch_select_name', array());
  522.         }
  523.  
  524.         $template->pparse('search_user_body');
  525.  
  526.         include("includes/page_tail_review.php");
  527.  
  528.         return;
  529. }
  530.  
  531. ?>