Просмотр файла includes/functions_search.php

Размер файла: 12.44Kb
  1. <?php
  2. /***************************************************************************
  3. * mides.ru
  4. * -------------------
  5. ***************************************************************************/
  6. function clean_words($mode, &$entry, &$stopword_list, &$synonym_list)
  7. {
  8. static $drop_char_match = array('^', '$', '&', '(', ')', '<', '>', '`', '\'', '"', '|', ',', '@', '_', '?', '%', '-', '~', '+', '.', '[', ']', '{', '}', ':', '\\', '/', '=', '#', '\'', ';', '!');
  9. static $drop_char_replace = array(' ', ' ', ' ', ' ', ' ', ' ', ' ', '', '', ' ', ' ', ' ', ' ', '', ' ', ' ', '', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' , ' ', ' ', ' ', ' ', ' ', ' ');
  10.  
  11. $entry = ' ' . strip_tags(strtolower($entry)) . ' ';
  12.  
  13. if ( $mode == 'post' )
  14. {
  15. $entry = preg_replace('/[\n\r]/is', ' ', $entry);
  16. $entry = preg_replace('/\b&[a-z]+;\b/', ' ', $entry);
  17. $entry = preg_replace('/\b[a-z0-9]+:\/\/[a-z0-9\.\-]+(\/[a-z0-9\?\.%_\-\+=&\/]+)?/', ' ', $entry);
  18. $entry = preg_replace('/\[img:[a-z0-9]{10,}\].*?\[\/img:[a-z0-9]{10,}\]/', ' ', $entry);
  19. $entry = preg_replace('/\[\/?url(=.*?)?\]/', ' ', $entry);
  20. $entry = preg_replace('/\[\/?[a-z\*=\+\-]+(\:?[0-9a-z]+)?:[a-z0-9]{10,}(\:[a-z0-9]+)?=?.*?\]/', ' ', $entry);
  21. }
  22. else if ( $mode == 'search' )
  23. {
  24. $entry = str_replace(' +', ' and ', $entry);
  25. $entry = str_replace(' -', ' not ', $entry);
  26. }
  27. for($i = 0; $i < count($drop_char_match); $i++)
  28. {
  29. $entry = str_replace($drop_char_match[$i], $drop_char_replace[$i], $entry);
  30. }
  31.  
  32. if ( $mode == 'post' )
  33. {
  34. $entry = str_replace('*', ' ', $entry);
  35.  
  36. // 'words' that consist of <3 or >20 characters are removed.
  37. $entry = preg_replace('/[ ]([\S]{1,2}|[\S]{21,})[ ]/',' ', $entry);
  38. }
  39.  
  40. if ( !empty($stopword_list) )
  41. {
  42. for ($j = 0; $j < count($stopword_list); $j++)
  43. {
  44. $stopword = trim($stopword_list[$j]);
  45.  
  46. if ( $mode == 'post' || ( $stopword != 'not' && $stopword != 'and' && $stopword != 'or' ) )
  47. {
  48. $entry = str_replace(' ' . trim($stopword) . ' ', ' ', $entry);
  49. }
  50. }
  51. }
  52.  
  53. if ( !empty($synonym_list) )
  54. {
  55. for ($j = 0; $j < count($synonym_list); $j++)
  56. {
  57. list($replace_synonym, $match_synonym) = split(' ', trim(strtolower($synonym_list[$j])));
  58. if ( $mode == 'post' || ( $match_synonym != 'not' && $match_synonym != 'and' && $match_synonym != 'or' ) )
  59. {
  60. $entry = str_replace(' ' . trim($match_synonym) . ' ', ' ' . trim($replace_synonym) . ' ', $entry);
  61. }
  62. }
  63. }
  64.  
  65. return $entry;
  66. }
  67.  
  68. function split_words($entry, $mode = 'post')
  69. {
  70.  
  71. return explode(' ', trim(preg_replace('#\s+#', ' ', $entry)));
  72. }
  73.  
  74. function add_search_words($mode, $post_id, $post_text, $post_title = '')
  75. {
  76. global $db, $phpbb_root_path, $board_config, $lang;
  77.  
  78. $stopword_array = @file($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . "/search_stopwords.txt");
  79. $synonym_array = @file($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . "/search_synonyms.txt");
  80.  
  81. $search_raw_words = array();
  82. $search_raw_words['text'] = split_words(clean_words('post', $post_text, $stopword_array, $synonym_array));
  83. $search_raw_words['title'] = split_words(clean_words('post', $post_title, $stopword_array, $synonym_array));
  84.  
  85. @set_time_limit(0);
  86.  
  87. $word = array();
  88. $word_insert_sql = array();
  89. while ( list($word_in, $search_matches) = @each($search_raw_words) )
  90. {
  91. $word_insert_sql[$word_in] = '';
  92. if ( !empty($search_matches) )
  93. {
  94. for ($i = 0; $i < count($search_matches); $i++)
  95. {
  96. $search_matches[$i] = trim($search_matches[$i]);
  97.  
  98. if( $search_matches[$i] != '' )
  99. {
  100. $word[] = $search_matches[$i];
  101. if ( !strstr($word_insert_sql[$word_in], "'" . $search_matches[$i] . "'") )
  102. {
  103. $word_insert_sql[$word_in] .= ( $word_insert_sql[$word_in] != "" ) ? ", '" . $search_matches[$i] . "'" : "'" . $search_matches[$i] . "'";
  104. }
  105. }
  106. }
  107. }
  108. }
  109.  
  110. if ( count($word) )
  111. {
  112. sort($word);
  113.  
  114. $prev_word = '';
  115. $word_text_sql = '';
  116. $temp_word = array();
  117. for($i = 0; $i < count($word); $i++)
  118. {
  119. if ( $word[$i] != $prev_word )
  120. {
  121. $temp_word[] = $word[$i];
  122. $word_text_sql .= ( ( $word_text_sql != '' ) ? ', ' : '' ) . "'" . $word[$i] . "'";
  123. }
  124. $prev_word = $word[$i];
  125. }
  126. $word = $temp_word;
  127.  
  128. $check_words = array();
  129. switch( SQL_LAYER )
  130. {
  131. case 'postgresql':
  132. case 'msaccess':
  133. case 'mssql-odbc':
  134. case 'oracle':
  135. case 'db2':
  136. $sql = "SELECT word_id, word_text
  137. FROM " . SEARCH_WORD_TABLE . "
  138. WHERE word_text IN ($word_text_sql)";
  139. if ( !($result = $db->sql_query($sql)) )
  140. {
  141. message_die(GENERAL_ERROR, 'Could not select words', '', __LINE__, __FILE__, $sql);
  142. }
  143.  
  144. while ( $row = $db->sql_fetchrow($result) )
  145. {
  146. $check_words[$row['word_text']] = $row['word_id'];
  147. }
  148. break;
  149. }
  150.  
  151. $value_sql = '';
  152. $match_word = array();
  153. for ($i = 0; $i < count($word); $i++)
  154. {
  155. $new_match = true;
  156. if ( isset($check_words[$word[$i]]) )
  157. {
  158. $new_match = false;
  159. }
  160.  
  161. if ( $new_match )
  162. {
  163. switch( SQL_LAYER )
  164. {
  165. case 'mysql':
  166. case 'mysql4':
  167. $value_sql .= ( ( $value_sql != '' ) ? ', ' : '' ) . '(\'' . $word[$i] . '\', 0)';
  168. break;
  169. case 'mssql':
  170. case 'mssql-odbc':
  171. $value_sql .= ( ( $value_sql != '' ) ? ' UNION ALL ' : '' ) . "SELECT '" . $word[$i] . "', 0";
  172. break;
  173. default:
  174. $sql = "INSERT INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)
  175. VALUES ('" . $word[$i] . "', 0)";
  176. if( !$db->sql_query($sql) )
  177. {
  178. message_die(GENERAL_ERROR, 'Could not insert new word', '', __LINE__, __FILE__, $sql);
  179. }
  180. break;
  181. }
  182. }
  183. }
  184.  
  185. if ( $value_sql != '' )
  186. {
  187. switch ( SQL_LAYER )
  188. {
  189. case 'mysql':
  190. case 'mysql4':
  191. $sql = "INSERT IGNORE INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)
  192. VALUES $value_sql";
  193. break;
  194. case 'mssql':
  195. case 'mssql-odbc':
  196. $sql = "INSERT INTO " . SEARCH_WORD_TABLE . " (word_text, word_common)
  197. $value_sql";
  198. break;
  199. }
  200.  
  201. if ( !$db->sql_query($sql) )
  202. {
  203. message_die(GENERAL_ERROR, 'Could not insert new word', '', __LINE__, __FILE__, $sql);
  204. }
  205. }
  206. }
  207.  
  208. while( list($word_in, $match_sql) = @each($word_insert_sql) )
  209. {
  210. $title_match = ( $word_in == 'title' ) ? 1 : 0;
  211.  
  212. if ( $match_sql != '' )
  213. {
  214. $sql = "INSERT INTO " . SEARCH_MATCH_TABLE . " (post_id, word_id, title_match)
  215. SELECT $post_id, word_id, $title_match
  216. FROM " . SEARCH_WORD_TABLE . "
  217. WHERE word_text IN ($match_sql)";
  218. if ( !$db->sql_query($sql) )
  219. {
  220. message_die(GENERAL_ERROR, 'Could not insert new word matches', '', __LINE__, __FILE__, $sql);
  221. }
  222. }
  223. }
  224.  
  225. if ($mode == 'single')
  226. {
  227. remove_common('single', 4/10, $word);
  228. }
  229.  
  230. return;
  231. }
  232.  
  233. function remove_common($mode, $fraction, $word_id_list = array())
  234. {
  235. global $db;
  236.  
  237. $sql = "SELECT COUNT(post_id) AS total_posts
  238. FROM " . POSTS_TABLE;
  239. if ( !($result = $db->sql_query($sql)) )
  240. {
  241. message_die(GENERAL_ERROR, 'Could not obtain post count', '', __LINE__, __FILE__, $sql);
  242. }
  243.  
  244. $row = $db->sql_fetchrow($result);
  245.  
  246. if ( $row['total_posts'] >= 100 )
  247. {
  248. $common_threshold = floor($row['total_posts'] * $fraction);
  249.  
  250. if ( $mode == 'single' && count($word_id_list) )
  251. {
  252. $word_id_sql = '';
  253. for($i = 0; $i < count($word_id_list); $i++)
  254. {
  255. $word_id_sql .= ( ( $word_id_sql != '' ) ? ', ' : '' ) . "'" . $word_id_list[$i] . "'";
  256. }
  257.  
  258. $sql = "SELECT m.word_id
  259. FROM " . SEARCH_MATCH_TABLE . " m, " . SEARCH_WORD_TABLE . " w
  260. WHERE w.word_text IN ($word_id_sql)
  261. AND m.word_id = w.word_id
  262. GROUP BY m.word_id
  263. HAVING COUNT(m.word_id) > $common_threshold";
  264. }
  265. else
  266. {
  267. $sql = "SELECT word_id
  268. FROM " . SEARCH_MATCH_TABLE . "
  269. GROUP BY word_id
  270. HAVING COUNT(word_id) > $common_threshold";
  271. }
  272.  
  273. if ( !($result = $db->sql_query($sql)) )
  274. {
  275. message_die(GENERAL_ERROR, 'Could not obtain common word list', '', __LINE__, __FILE__, $sql);
  276. }
  277.  
  278. $common_word_id = '';
  279. while ( $row = $db->sql_fetchrow($result) )
  280. {
  281. $common_word_id .= ( ( $common_word_id != '' ) ? ', ' : '' ) . $row['word_id'];
  282. }
  283. $db->sql_freeresult($result);
  284.  
  285. if ( $common_word_id != '' )
  286. {
  287. $sql = "UPDATE " . SEARCH_WORD_TABLE . "
  288. SET word_common = " . TRUE . "
  289. WHERE word_id IN ($common_word_id)";
  290. if ( !$db->sql_query($sql) )
  291. {
  292. message_die(GENERAL_ERROR, 'Could not delete word list entry', '', __LINE__, __FILE__, $sql);
  293. }
  294.  
  295. $sql = "DELETE FROM " . SEARCH_MATCH_TABLE . "
  296. WHERE word_id IN ($common_word_id)";
  297. if ( !$db->sql_query($sql) )
  298. {
  299. message_die(GENERAL_ERROR, 'Could not delete word match entry', '', __LINE__, __FILE__, $sql);
  300. }
  301. }
  302. }
  303.  
  304. return;
  305. }
  306.  
  307. function remove_search_post($post_id_sql)
  308. {
  309. global $db;
  310.  
  311. $words_removed = false;
  312.  
  313. switch ( SQL_LAYER )
  314. {
  315. case 'mysql':
  316. case 'mysql4':
  317. $sql = "SELECT word_id
  318. FROM " . SEARCH_MATCH_TABLE . "
  319. WHERE post_id IN ($post_id_sql)
  320. GROUP BY word_id";
  321. if ( $result = $db->sql_query($sql) )
  322. {
  323. $word_id_sql = '';
  324. while ( $row = $db->sql_fetchrow($result) )
  325. {
  326. $word_id_sql .= ( $word_id_sql != '' ) ? ', ' . $row['word_id'] : $row['word_id'];
  327. }
  328.  
  329. $sql = "SELECT word_id
  330. FROM " . SEARCH_MATCH_TABLE . "
  331. WHERE word_id IN ($word_id_sql)
  332. GROUP BY word_id
  333. HAVING COUNT(word_id) = 1";
  334. if ( $result = $db->sql_query($sql) )
  335. {
  336. $word_id_sql = '';
  337. while ( $row = $db->sql_fetchrow($result) )
  338. {
  339. $word_id_sql .= ( $word_id_sql != '' ) ? ', ' . $row['word_id'] : $row['word_id'];
  340. }
  341.  
  342. if ( $word_id_sql != '' )
  343. {
  344. $sql = "DELETE FROM " . SEARCH_WORD_TABLE . "
  345. WHERE word_id IN ($word_id_sql)";
  346. if ( !$db->sql_query($sql) )
  347. {
  348. message_die(GENERAL_ERROR, 'Could not delete word list entry', '', __LINE__, __FILE__, $sql);
  349. }
  350.  
  351. $words_removed = $db->sql_affectedrows();
  352. }
  353. }
  354. }
  355. break;
  356.  
  357. default:
  358. $sql = "DELETE FROM " . SEARCH_WORD_TABLE . "
  359. WHERE word_id IN (
  360. SELECT word_id
  361. FROM " . SEARCH_MATCH_TABLE . "
  362. WHERE word_id IN (
  363. SELECT word_id
  364. FROM " . SEARCH_MATCH_TABLE . "
  365. WHERE post_id IN ($post_id_sql)
  366. GROUP BY word_id
  367. )
  368. GROUP BY word_id
  369. HAVING COUNT(word_id) = 1
  370. )";
  371. if ( !$db->sql_query($sql) )
  372. {
  373. message_die(GENERAL_ERROR, 'Could not delete old words from word table', '', __LINE__, __FILE__, $sql);
  374. }
  375.  
  376. $words_removed = $db->sql_affectedrows();
  377.  
  378. break;
  379. }
  380.  
  381. $sql = "DELETE FROM " . SEARCH_MATCH_TABLE . "
  382. WHERE post_id IN ($post_id_sql)";
  383. if ( !$db->sql_query($sql) )
  384. {
  385. message_die(GENERAL_ERROR, 'Error in deleting post', '', __LINE__, __FILE__, $sql);
  386. }
  387.  
  388. return $words_removed;
  389. }
  390.  
  391. function username_search($search_match)
  392. {
  393. global $db, $board_config, $template, $lang, $phpEx, $phpbb_root_path;
  394. global $starttime, $gen_simple_header;
  395. $gen_simple_header = false;
  396.  
  397. $username_list = '';
  398. if ( !empty($search_match) )
  399. {
  400. $username_search = preg_replace('/\*/', '%', phpbb_clean_username($search_match));
  401.  
  402. $sql = "SELECT username, user_id
  403. FROM " . USERS_TABLE . "
  404. WHERE username LIKE '" . str_replace("\'", "''", $username_search) . "' AND user_id <> " . ANONYMOUS . "
  405. ORDER BY username";
  406. if ( !($result = $db->sql_query($sql)) )
  407. {
  408. message_die(GENERAL_ERROR, 'Could not obtain search results', '', __LINE__, __FILE__, $sql);
  409. }
  410.  
  411. if ( $row = $db->sql_fetchrow($result) )
  412. {
  413. do
  414. {
  415. $username_list .= '<option value="' . $row['user_id'] . '">' . $row['username'] . '</option>';
  416. }
  417. while ( $row = $db->sql_fetchrow($result) );
  418. }
  419. else
  420. {
  421. $username_list .= '<option>' . $lang['No_match']. '</option>';
  422. }
  423. $db->sql_freeresult($result);
  424. }
  425.  
  426. $page_title = 'Поиск пользователей';
  427. include($phpbb_root_path . 'includes/page_header.'.$phpEx);
  428.  
  429. $template->set_filenames(array(
  430. 'search_user_body' => 'search_username.tpl')
  431. );
  432.  
  433. $template->assign_vars(array(
  434. 'USERNAME' => (!empty($search_match)) ? phpbb_clean_username($search_match) : '',
  435.  
  436. 'L_CLOSE_WINDOW' => $lang['Close_window'],
  437. 'L_SEARCH_USERNAME' => $lang['Find_username'],
  438. 'L_UPDATE_USERNAME' => $lang['Select_username'],
  439. 'L_SELECT' => $lang['Select'],
  440. 'L_SEARCH' => $lang['Search'],
  441. 'L_SEARCH_EXPLAIN' => $lang['Search_author_explain'],
  442. 'L_CLOSE_WINDOW' => $lang['Close_window'],
  443.  
  444. 'S_USERNAME_OPTIONS' => $username_list,
  445. 'S_SEARCH_ACTION' => append_sid("search.$phpEx?mode=searchuser"))
  446. );
  447.  
  448. if ( $username_list != '' )
  449. {
  450. $template->assign_block_vars('switch_select_name', array());
  451. }
  452.  
  453. $template->pparse('search_user_body');
  454.  
  455. include($phpbb_root_path . 'includes/page_tail.'.$phpEx);
  456.  
  457. return;
  458. }
  459.  
  460. ?>