632 lines
26 KiB
PHP
632 lines
26 KiB
PHP
<?php
|
|
/******************************************************************************
|
|
* Search.php *
|
|
*******************************************************************************
|
|
* SMF: Simple Machines Forum *
|
|
* Open-Source Project Inspired by Zef Hemel (zef@zefhemel.com) *
|
|
* =========================================================================== *
|
|
* Software Version: SMF 1.0.7 *
|
|
* Software by: Simple Machines (http://www.simplemachines.org) *
|
|
* Copyright 2001-2005 by: Lewis Media (http://www.lewismedia.com) *
|
|
* Support, News, Updates at: http://www.simplemachines.org *
|
|
*******************************************************************************
|
|
* This program is free software; you may redistribute it and/or modify it *
|
|
* under the terms of the provided license as published by Lewis Media. *
|
|
* *
|
|
* This program is distributed in the hope that it is and will be useful, *
|
|
* but WITHOUT ANY WARRANTIES; without even any implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
* *
|
|
* See the "license.txt" file for details of the Simple Machines license. *
|
|
* The latest version can always be found at http://www.simplemachines.org. *
|
|
******************************************************************************/
|
|
if (!defined('SMF'))
|
|
die('Hacking attempt...');
|
|
|
|
/* These functions are here for searching, and they are:
|
|
|
|
void PlushSearch1()
|
|
- shows the screen to search forum posts (action=search), and uses the
|
|
simple version if the simpleSearch setting is enabled.
|
|
- uses the main sub template of the Search template.
|
|
- requires the search_posts permission.
|
|
- decodes and loads search parameters given in the URL (if any).
|
|
- the form redirects to index.php?action=search2.
|
|
|
|
void PlushSearch2()
|
|
- checks user input and searches the messages table for messages
|
|
matching the query.
|
|
- requires the search_posts permission.
|
|
- stores the results into the search cache (if enabled).
|
|
- show the results of the search query.
|
|
- uses the results sub template of the Search template.
|
|
|
|
array prepareSearchContext(bool reset = false)
|
|
- callback function for the results sub template.
|
|
- loads the necessary contextual data to show a search result.
|
|
*/
|
|
// Quick'n'dirty search by just topic title
|
|
function QuickSearch()
|
|
{
|
|
|
|
global $sourcedir, $scripturl, $txt, $db_prefix, $user_info, $context, $messages_request, $attachments, $boards_can, $modSettings;
|
|
|
|
|
|
loadTemplate('Newsearch');
|
|
|
|
// Check the user's permissions.
|
|
isAllowedTo('search_posts');
|
|
|
|
// Link tree....
|
|
$context['linktree'][] = array(
|
|
'url' => $scripturl . '?action=search',
|
|
'name' => $txt[182]
|
|
);
|
|
|
|
$context['compact'] = true;
|
|
// Create an array for the permissions.
|
|
$boards_can = array(
|
|
'post_reply_own' => boardsAllowedTo('post_reply_own'),
|
|
'post_reply_any' => boardsAllowedTo('post_reply_any'),
|
|
'mark_any_notify' => boardsAllowedTo('mark_any_notify')
|
|
);
|
|
|
|
require_once($sourcedir . '/Display.php');
|
|
|
|
include('/var/www/rock/forum/sphinx/sphinxapi.php');
|
|
|
|
if (isset ($_GET['start'])) {
|
|
$start = intval ($_GET['start']);
|
|
if ($start < 0) $start=0;
|
|
} else {
|
|
$start = 0;
|
|
}
|
|
|
|
$cl = new SphinxClient();
|
|
$cl->SetServer( "localhost", 9312 );
|
|
$cl->SetMatchMode( SPH_MATCH_EXTENDED2 );
|
|
$cl->SetLimits($start, intval ($modSettings['search_results_per_page']));
|
|
$cl->SetArrayResult( true );
|
|
|
|
$q = $cl->EscapeString ($_GET['search']);
|
|
$result = $cl->Query( "@(subject) $q", 'topics ' );
|
|
|
|
$msgs = array();
|
|
$subjects = array();
|
|
$bodies = array();
|
|
|
|
$context['messages'] = array();
|
|
$context['topics'] = array();
|
|
if (! empty ($result['matches'])) {
|
|
foreach ($result['matches'] as $doc) {
|
|
$context['messages'][] = $doc['id']; //$doc['attrs']['id_msg'];
|
|
$context['topics'][$doc['id']]['id'] = $doc['attrs']['id_topic'];
|
|
}
|
|
|
|
$messages_request = db_query("SELECT m.*, b.name as bName
|
|
FROM smf_messages m, smf_boards b
|
|
WHERE m.ID_BOARD=b.ID_BOARD
|
|
AND ID_MSG IN(".implode(',', $context['messages']).")",
|
|
__FILE__, __LINE__);
|
|
}
|
|
|
|
$context['key_words'] = array_keys($result['words']);
|
|
|
|
// Now that we know how many results to expect we can start calculating the page numbers.
|
|
$context['page_index'] = constructPageIndex($scripturl . '?action=qsearch;search=' . urlencode($_GET['search']), $_REQUEST['start'], (int) $result['total_found'], $modSettings['search_results_per_page'], false);
|
|
|
|
// Set the basic stuff for the template.
|
|
$context['allow_hide_email'] = !empty($modSettings['allow_hideEmail']);
|
|
|
|
$context['sub_template'] = 'results';
|
|
$context['page_title'] = $txt[166];
|
|
$context['get_topics'] = 'prepareSearchContext';
|
|
$context['can_send_pm'] = allowedTo('pm_send');
|
|
|
|
loadJumpTo();
|
|
}
|
|
|
|
// Ask the user what they want to search for.
|
|
function PlushSearch1()
|
|
{
|
|
global $txt, $scripturl, $db_prefix, $modSettings, $user_info, $context;
|
|
|
|
loadTemplate('Newsearch');
|
|
|
|
// Check the user's permissions.
|
|
isAllowedTo('search_posts');
|
|
|
|
// Link tree....
|
|
$context['linktree'][] = array(
|
|
'url' => $scripturl . '?action=search',
|
|
'name' => $txt[182]
|
|
);
|
|
|
|
// If you got back from search2 by using the linktree, you get your original search parameters back.
|
|
if (isset($_REQUEST['params']))
|
|
{
|
|
$temp_params = explode('|"|', base64_decode($_REQUEST['params']));
|
|
$context['search_params'] = array();
|
|
foreach ($temp_params as $i => $data)
|
|
{
|
|
list ($k, $v) = explode('|\'|', $data);
|
|
$context['search_params'][$k] = stripslashes($v);
|
|
}
|
|
if (isset($context['search_params']['brd']))
|
|
$context['search_params']['brd'] = $context['search_params']['brd'] == '' ? array() : explode(',', $context['search_params']['brd']);
|
|
}
|
|
|
|
if (isset($context['search_params']['search']))
|
|
$context['search_params']['search'] = htmlspecialchars($context['search_params']['search']);
|
|
if (isset($context['search_params']['userspec']))
|
|
$context['search_params']['userspec'] = htmlspecialchars(stripslashes($context['search_params']['userspec']));
|
|
|
|
// Find all the boards this user is allowed to see.
|
|
$request = db_query("
|
|
SELECT b.ID_CAT, c.name AS catName, b.ID_BOARD, b.name, b.childLevel
|
|
FROM {$db_prefix}boards AS b
|
|
LEFT JOIN {$db_prefix}categories AS c ON (c.ID_CAT = b.ID_CAT)
|
|
WHERE $user_info[query_see_board]
|
|
ORDER BY c.catOrder, b.boardOrder", __FILE__, __LINE__);
|
|
$context['num_boards'] = mysql_num_rows($request);
|
|
$context['categories'] = array();
|
|
while ($row = mysql_fetch_assoc($request))
|
|
{
|
|
// This category hasn't been set up yet..
|
|
if (!isset($context['categories'][$row['ID_CAT']]))
|
|
$context['categories'][$row['ID_CAT']] = array(
|
|
'id' => $row['ID_CAT'],
|
|
'name' => $row['catName'],
|
|
'boards' => array()
|
|
);
|
|
|
|
// Set this board up, and let the template know when it's a child. (indent them..)
|
|
$context['categories'][$row['ID_CAT']]['boards'][$row['ID_BOARD']] = array(
|
|
'id' => $row['ID_BOARD'],
|
|
'name' => $row['name'],
|
|
'child_level' => $row['childLevel']
|
|
);
|
|
}
|
|
mysql_free_result($request);
|
|
|
|
// Simple or not?
|
|
$context['simple_search'] = !empty($modSettings['simpleSearch']) && !isset($_GET['advanced']);
|
|
$context['page_title'] = $txt[183];
|
|
}
|
|
|
|
// Gather the results and show them.
|
|
function PlushSearch2()
|
|
{
|
|
global $modSettings, $sourcedir;
|
|
global $scripturl, $txt, $db_prefix, $user_info, $context, $messages_request, $attachments, $boards_can;
|
|
|
|
loadTemplate('Newsearch');
|
|
|
|
// Are you allowed?
|
|
isAllowedTo('search_posts');
|
|
|
|
// So, we're allowed here, let's clean up the start variable - just incase.
|
|
$_REQUEST['start'] = (int) $_REQUEST['start'];
|
|
|
|
require_once($sourcedir . '/Display.php');
|
|
|
|
// $search_params will carry all settings that differ from the default search parameters.
|
|
// That way, the URLs involved in a search page will be kept as short as possible.
|
|
$search_params = array();
|
|
|
|
if (isset($_REQUEST['params']))
|
|
{
|
|
$temp_params = explode('|"|', base64_decode($_REQUEST['params']));
|
|
foreach ($temp_params as $i => $data)
|
|
{
|
|
list ($k, $v) = explode('|\'|', $data);
|
|
$search_params[$k] = stripslashes($v);
|
|
}
|
|
if (isset($search_params['brd']))
|
|
$search_params['brd'] = $search_params['brd'] == '' ? array() : explode(',', $search_params['brd']);
|
|
}
|
|
else
|
|
{
|
|
$search_params['subject_only'] = true;
|
|
}
|
|
|
|
|
|
// 1 => 'allwords' (default, don't set as param) / 2 => 'anywords'.
|
|
if (!empty($search_params['searchtype']) || (!empty($_REQUEST['searchtype']) && $_REQUEST['searchtype'] == 2))
|
|
$search_params['searchtype'] = 2;
|
|
|
|
// Minimum age of messages. Default to zero (don't set param in that case).
|
|
if (!empty($search_params['minage']) || (!empty($_REQUEST['minage']) && $_REQUEST['minage'] > 0))
|
|
$search_params['minage'] = !empty($search_params['minage']) ? (int) $search_params['minage'] : (int) $_REQUEST['minage'];
|
|
|
|
// Maximum age of messages. Default to infinite (9999 days: param not set).
|
|
if (!empty($search_params['maxage']) || (!empty($_REQUEST['maxage']) && $_REQUEST['maxage'] != 9999))
|
|
$search_params['maxage'] = !empty($search_params['maxage']) ? (int) $search_params['maxage'] : (int) $_REQUEST['maxage'];
|
|
|
|
$timeAddition = '';
|
|
$timeAddition .= !empty($search_params['minage']) ? ' AND m.posterTime <= ' . (time() - $search_params['minage'] * 86400) : '';
|
|
$timeAddition .= !empty($search_params['maxage']) ? ' AND m.posterTime >= ' . (time() - $search_params['maxage'] * 86400) : '';
|
|
|
|
// Default the user name to a wildcard matching every user (*).
|
|
if (!empty($search_params['user_spec']) || (!empty($_REQUEST['userspec']) && $_REQUEST['userspec'] != '*'))
|
|
$search_params['userspec'] = isset($search_params['userspec']) ? $search_params['userspec'] : $_REQUEST['userspec'];
|
|
|
|
// If there's no specific user, then don't mention it in the main query.
|
|
if (empty($search_params['userspec']))
|
|
$userQuery = '';
|
|
else
|
|
{
|
|
$userString = strtolower(addslashes(strtr($search_params['userspec'], array('%' => '\%', '_' => '\_', '*' => '%', '?' => '_'))));
|
|
// Retrieve a list of possible members.
|
|
$request = db_query("
|
|
SELECT ID_MEMBER
|
|
FROM {$db_prefix}members
|
|
WHERE realName LIKE '$userString'", __FILE__, __LINE__);
|
|
// Simply do nothing if there're too many members matching the criteria.
|
|
if (mysql_num_rows($request) > $maxMembersToSearch)
|
|
$userQuery = '';
|
|
elseif (mysql_num_rows($request) == 0)
|
|
$userQuery = "m.ID_MEMBER = 0 AND m.posterName LIKE '$userString'";
|
|
else
|
|
{
|
|
$memberlist = array();
|
|
while ($row = mysql_fetch_assoc($request))
|
|
$memberlist[] = $row['ID_MEMBER'];
|
|
$userQuery = "(m.ID_MEMBER IN (" . implode(', ', $memberlist) . ") OR (m.ID_MEMBER = 0 AND m.posterName LIKE '$userString'))";
|
|
}
|
|
}
|
|
|
|
// If the boards were passed by URL (params=), temporarily put them back in $_REQUEST.
|
|
if (!empty($search_params['brd']) && is_array($search_params['brd']))
|
|
$_REQUEST['brd'] = $search_params['brd'];
|
|
|
|
// Make sure all boards are integers.
|
|
if (!empty($_REQUEST['brd']))
|
|
foreach ($_REQUEST['brd'] as $id => $brd)
|
|
$_REQUEST['brd'][$id] = (int) $brd;
|
|
|
|
// Select all boards you've selected AND are allowed to see.
|
|
if ($user_info['is_admin'])
|
|
$search_params['brd'] = empty($_REQUEST['brd']) ? array() : $_REQUEST['brd'];
|
|
else
|
|
{
|
|
$request = db_query("
|
|
SELECT b.ID_BOARD
|
|
FROM {$db_prefix}boards AS b
|
|
WHERE $user_info[query_see_board]" . (empty($_REQUEST['brd']) ? '' : "
|
|
AND b.ID_BOARD IN (" . implode(', ', $_REQUEST['brd']) . ")"), __FILE__, __LINE__);
|
|
$search_params['brd'] = array();
|
|
while ($row = mysql_fetch_assoc($request))
|
|
$search_params['brd'][] = $row['ID_BOARD'];
|
|
mysql_free_result($request);
|
|
|
|
// This error should pro'bly only happen for hackers.
|
|
if (empty($search_params['brd']))
|
|
fatal_lang_error('search_no_boards');
|
|
}
|
|
|
|
$search_params['show_complete'] = !empty($search_params['show_complete']) || !empty($_REQUEST['show_complete']);
|
|
$search_params['subject_only'] = !empty($search_params['subject_only']) || !empty($_REQUEST['subject_only']);
|
|
|
|
$context['compact'] = !$search_params['show_complete'];
|
|
|
|
// What are we searching for?
|
|
$search_params['search'] = !empty($search_params['search']) ? $search_params['search'] : (isset($_REQUEST['search']) ? stripslashes($_REQUEST['search']) : '');
|
|
// Nothing??
|
|
if (!isset($search_params['search']) || $search_params['search'] == '')
|
|
fatal_lang_error('no_valid_search_string', false);
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
// That's all, I guess. Following is some weird stuff used by previous search
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//if (0) { // игнорируем это пока
|
|
|
|
// Extract phrase parts first (e.g. some words "this is a phrase" some more words.)
|
|
preg_match_all('/(?:^|\s)"([^"]+)"(?:$|\s)/', $search_params['search'], $matches, PREG_PATTERN_ORDER);
|
|
$searchArray = $matches[1];
|
|
|
|
// Remove the phrase parts and extract the words.
|
|
$searchArray = array_merge($searchArray, explode(' ', preg_replace('/(?:^|\s)"([^"]+)"(?:$|\s)/', ' ', $search_params['search'])));
|
|
|
|
// Trim everything and make sure there are no words that are the same.
|
|
foreach ($searchArray as $index => $value)
|
|
{
|
|
$searchArray[$index] = addslashes(strtolower(trim($value)));
|
|
if (!isset($searchArray[$index]) || $searchArray[$index] == '')
|
|
unset($searchArray[$index]);
|
|
}
|
|
$searchArray = array_slice(array_unique($searchArray), 0, 10);
|
|
|
|
if (empty($searchArray))
|
|
fatal_lang_error('no_valid_search_string', false);
|
|
|
|
// Each word is matched against the body and the subject.
|
|
$searchParts = array();
|
|
foreach ($searchArray as $word)
|
|
{
|
|
if (empty($modSettings['search_match_complete_words']))
|
|
$searchParts[] = " LIKE '%" . strtr($word, array('_' => '\\_', '%' => '\\%')) . "%'";
|
|
else
|
|
$searchParts[] = " RLIKE '[[:<:]]" . addcslashes(preg_replace(array('/([\[\]$.+?|{}])/', '/\*/'), array('[$1]', '.+'), $word), '') . "[[:>:]]'";
|
|
}
|
|
|
|
$searchQuery = 0;
|
|
|
|
|
|
// Either all words must match (searchtype == 1) or any of the words (searchtype == 2).
|
|
if (empty($search_params['searchtype']))
|
|
{
|
|
// искать по содержимому сообщений
|
|
if (!$search_params['subject_only'])
|
|
$searchQuery = 'm.body' . implode(' AND m.body', $searchParts) . $timeAddition;
|
|
// только по темам
|
|
$topicQuery = 'm.subject' . implode(' AND m.subject', $searchParts) . $timeAddition;
|
|
}
|
|
else
|
|
{
|
|
if (!$search_params['subject_only'])
|
|
$searchQuery = (count($searchParts) > 1 ? '(' : '') . 'm.body' . implode(' OR m.body', $searchParts) . (count($searchParts) > 1 ? ')' : '') . $timeAddition;
|
|
$topicQuery = (count($searchParts) > 1 ? '(' : '') . 'm.subject' . implode(' OR m.subject', $searchParts) . (count($searchParts) > 1 ? ')' : '') . $timeAddition;
|
|
}
|
|
|
|
// Get the sorting parameters right. Default to sort by relevance descending.
|
|
$sort_columns = array(
|
|
'relevance',
|
|
'numReplies',
|
|
'ID_MSG',
|
|
);
|
|
if (empty($search_params['sort']) && !empty($_REQUEST['sort']))
|
|
list ($search_params['sort'], $search_params['sort_dir']) = array_pad(explode('|', $_REQUEST['sort']), 2, '');
|
|
$search_params['sort'] = !empty($search_params['sort']) && in_array($search_params['sort'], $sort_columns) ? $search_params['sort'] : 'relevance';
|
|
$search_params['sort_dir'] = !empty($search_params['sort_dir']) && $search_params['sort_dir'] == 'asc' ? 'asc' : 'desc';
|
|
|
|
$context['mark'] = array();
|
|
# foreach ($searchArray as $word)
|
|
# $context['mark'][$word] = '<b class="highlight">' . $word . '</b>';
|
|
|
|
// All search params have been checked, let's compile them to a single string... made less simple by PHP 4.3.9 and below.
|
|
$temp_params = $search_params;
|
|
if (isset($temp_params['brd']))
|
|
$temp_params['brd'] = implode(',', $temp_params['brd']);
|
|
$context['params'] = array();
|
|
foreach ($temp_params as $k => $v)
|
|
$context['params'][] = $k . '|\'|' . addslashes($v);
|
|
$context['params'] = base64_encode(implode('|"|', $context['params']));
|
|
|
|
// ... and add the links to the link tree.
|
|
$context['linktree'][] = array(
|
|
'url' => $scripturl . '?action=search;params=' . $context['params'],
|
|
'name' => $txt[182]
|
|
);
|
|
$context['linktree'][] = array(
|
|
'url' => $scripturl . '?action=search2;params=' . $context['params'],
|
|
'name' => $txt['search_results']
|
|
);
|
|
|
|
// Create an array for the permissions.
|
|
$boards_can = array(
|
|
'post_reply_own' => boardsAllowedTo('post_reply_own'),
|
|
'post_reply_any' => boardsAllowedTo('post_reply_any'),
|
|
'mark_any_notify' => boardsAllowedTo('mark_any_notify')
|
|
);
|
|
|
|
include('/var/www/rock/forum/sphinx/sphinxapi.php');
|
|
$cl = new SphinxClient();
|
|
$cl->SetServer( "localhost", 9312 );
|
|
$cl->SetMatchMode( SPH_MATCH_EXTENDED );
|
|
$cl->SetSortMode( SPH_SORT_RELEVANCE );
|
|
//$cl->SetGroupBy ( "ID_TOPIC", SPH_GROUPBY_ATTR, '@weight DESC');
|
|
# $cl->SetFieldWeights(array('subject'=>10, 'body'=>1));
|
|
# $cl->SetSelect( 'ID_MSG as id_msg');
|
|
$cl->SetLimits($_REQUEST[start], intval($modSettings['search_results_per_page']));
|
|
$cl->SetFilter( 'id_board', $search_params['brd'] );
|
|
$cl->SetArrayResult( true );
|
|
$q = $cl->EscapeString ($search_params['search']);
|
|
$result = $cl->Query( "@(subject) $q @(body) $q", 'posts_main posts_delta ' );
|
|
|
|
$context['messages'] = array();
|
|
$context['topics'] = array();
|
|
foreach ($result['matches'] as $doc) {
|
|
$context['messages'][] = $doc['id']; //$doc['attrs']['id_msg'];
|
|
$context['topics'][$doc['id']]['id'] = $doc['attrs']['id_topic'];
|
|
}
|
|
|
|
$messages_request = db_query("SELECT m.*, b.name as bName
|
|
FROM smf_messages m, smf_boards b
|
|
WHERE m.ID_BOARD=b.ID_BOARD
|
|
AND ID_MSG IN(".implode(',', $context['messages']).")",
|
|
__FILE__, __LINE__);
|
|
|
|
|
|
$context['key_words'] = &$searchArray;
|
|
|
|
// Set the basic stuff for the template.
|
|
$context['allow_hide_email'] = !empty($modSettings['allow_hideEmail']);
|
|
|
|
$context['sub_template'] = 'results';
|
|
$context['page_title'] = $txt[166];
|
|
$context['get_topics'] = 'prepareSearchContext';
|
|
$context['can_send_pm'] = allowedTo('pm_send');
|
|
|
|
loadJumpTo();
|
|
}
|
|
|
|
// Callback to return messages - saves memory.
|
|
function prepareSearchContext($reset = false)
|
|
{
|
|
global $txt, $modSettings, $scripturl, $ID_MEMBER;
|
|
global $themeUser, $context, $messages_request, $db_prefix, $attachments, $boards_can;
|
|
|
|
// Remember which message this is. (ie. reply #83)
|
|
static $counter = null;
|
|
if ($counter == null || $reset)
|
|
$counter = $_REQUEST['start'] + 1;
|
|
|
|
// If the query returned false, bail.
|
|
if ($messages_request == false)
|
|
return false;
|
|
|
|
// Start from the beginning...
|
|
if ($reset)
|
|
return @mysql_data_seek($messages_request, 0);
|
|
|
|
// Attempt to get the next message.
|
|
$message = mysql_fetch_assoc($messages_request);
|
|
if (!$message)
|
|
return false;
|
|
|
|
// Can't have an empty subject can we?
|
|
$message['subject'] = $message['subject'] != '' ? $message['subject'] : $txt[24];
|
|
$message['first_subject'] = $message['first_subject'] != '' ? $message['first_subject'] : $txt[24];
|
|
|
|
// If it couldn't load, or the user was a guest.... someday may be done with a guest table.
|
|
if (!loadMemberContext($message['ID_MEMBER']))
|
|
{
|
|
// Notice this information isn't used anywhere else.... *cough guest table cough*
|
|
$themeUser[$message['ID_MEMBER']]['name'] = $message['posterName'];
|
|
$themeUser[$message['ID_MEMBER']]['id'] = 0;
|
|
$themeUser[$message['ID_MEMBER']]['group'] = $txt[28];
|
|
$themeUser[$message['ID_MEMBER']]['link'] = $message['posterName'];
|
|
$themeUser[$message['ID_MEMBER']]['email'] = $message['posterEmail'];
|
|
}
|
|
$themeUser[$message['ID_MEMBER']]['ip'] = $message['posterIP'];
|
|
|
|
// Do the censor thang...
|
|
censorText($message['body']);
|
|
censorText($message['subject']);
|
|
|
|
censorText($message['first_subject']);
|
|
|
|
// Shorten this message if necessary.
|
|
if ($context['compact'])
|
|
{
|
|
// Set the number of characters before and after the searched keyword.
|
|
$charLimit = 40;
|
|
|
|
$message['body'] = strtr($message['body'], array("\n" => ' ', '<br />' => "\n"));
|
|
$message['body'] = doUBBC($message['body'], $message['smileysEnabled']);
|
|
$message['body'] = strip_tags($message['body']);
|
|
|
|
if (strlen($message['body']) > $charLimit)
|
|
{
|
|
if (empty($context['key_words']))
|
|
$message['body'] = htmlspecialchars(mb_substr(un_htmlspecialchars($message['body']), 0, $charLimit) . (mb_strlen($message['body']) > $charLimit ? '<b>...</b>' : ''), ENT_QUOTES);
|
|
else
|
|
{
|
|
$matchString = '';
|
|
foreach ($context['key_words'] as $keyword)
|
|
$matchString .= strtr(preg_quote($keyword, '/'), array('\*' => '.+?')) . '|';
|
|
$matchString = mb_substr($matchString, 0, -1);
|
|
$message['body'] = un_htmlspecialchars(str_replace(' ', ' ', $message['body']));
|
|
if (empty($modSettings['search_match_complete_words']))
|
|
preg_match_all('/([^\s\W]{' . $charLimit . '}[\s\W]|[\s\W].{0,' . $charLimit . '}?|^)(' . $matchString . ')(.{0,' . $charLimit . '}[\s\W]|[^\s\W]{' . $charLimit . '})/isu', $message['body'], $matches);
|
|
else
|
|
preg_match_all('/([^\s\W]{' . $charLimit . '}[\s\W]|[\s\W].{0,' . $charLimit . '}?[\s\W]|^)(' . $matchString . ')([\s\W].{0,' . $charLimit . '}[\s\W]|[\s\W][^\s\W]{' . $charLimit . '})/isu', $message['body'], $matches);
|
|
$message['body'] = '';
|
|
foreach ($matches[0] as $index => $match) {
|
|
if ($index > 2) break;
|
|
$message['body'] .= '<b>...</b> ' . htmlspecialchars($match, ENT_QUOTES) . ' <b>...</b><br />';
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Run UBBC interpreter on the message.
|
|
$message['body'] = doUBBC($message['body'], $message['smileysEnabled']);
|
|
}
|
|
/// костыль!
|
|
$message['last_posterTime'] = $message['posterTime'];
|
|
$message['first_posterTime'] = $message['posterTime'];
|
|
$output = array_merge($context['topics'][$message['ID_MSG']], array(
|
|
'is_sticky' => !empty($modSettings['enableStickyTopics']) && !empty($message['isSticky']),
|
|
'is_locked' => !empty($message['locked']),
|
|
'is_poll' => $modSettings['pollMode'] == '1' && $message['ID_POLL'] > 0,
|
|
'is_hot' => $message['numReplies'] >= $modSettings['hotTopicPosts'],
|
|
'is_very_hot' => $message['numReplies'] >= $modSettings['hotTopicVeryPosts'],
|
|
'views' => $message['numViews'],
|
|
'replies' => $message['numReplies'],
|
|
'can_reply' => in_array($message['ID_BOARD'], $boards_can['post_reply_any']) || in_array(0, $boards_can['post_reply_any']),
|
|
'can_mark_notify' => in_array($message['ID_BOARD'], $boards_can['mark_any_notify']) || in_array(0, $boards_can['mark_any_notify']),
|
|
'first_post' => array(
|
|
'id' => $message['first_msg'],
|
|
'time' => timeformat($message['first_posterTime']),
|
|
'subject' => $message['subject'],
|
|
'href' => $scripturl . '?topic=' . $message['ID_TOPIC'] . '.0',
|
|
'link' => '<a href="' . $scripturl . '?topic=' . $message['ID_TOPIC'] . '.0">' . $message['subject'] . '</a>',
|
|
'icon' => $message['icon'],
|
|
'member' => array(
|
|
'id' => $message['first_member_id'],
|
|
'name' => $message['first_member_name'],
|
|
'href' => !empty($message['first_member_id']) ? $scripturl . '?action=profile;u=' . $message['first_member_id'] : '',
|
|
'link' => !empty($message['first_member_id']) ? '<a href="' . $scripturl . '?action=profile;u=' . $message['first_member_id'] . '" title="' . $txt[92] . ' ' . $message['first_member_name'] . '">' . $message['first_member_name'] . '</a>' : $message['first_member_name']
|
|
)
|
|
),
|
|
'last_post' => array(
|
|
'id' => $message['last_msg'],
|
|
'time' => timeformat($message['last_posterTime']),
|
|
'timestamp' => $message['last_posterTime'],
|
|
'member' => array(
|
|
'id' => $message['last_member_id'],
|
|
'name' => $message['last_member_name'],
|
|
'href' => !empty($message['last_member_id']) ? $scripturl . '?action=profile;u=' . $message['last_member_id'] : '',
|
|
'link' => !empty($message['last_member_id']) ? '<a href="' . $scripturl . '?action=profile;u=' . $message['last_member_id'] . '" title="' . $txt[92] . ' ' . $message['last_member_name'] . '">' . $message['last_member_name'] . '</a>' : $message['last_member_name']
|
|
)
|
|
),
|
|
'board' => array(
|
|
'id' => $message['ID_BOARD'],
|
|
'name' => $message['bName'],
|
|
'href' => $scripturl . '?board=' . $message['ID_BOARD'] . '.0',
|
|
'link' => '<a href="' . $scripturl . '?board=' . $message['ID_BOARD'] . '.0">' . $message['bName'] . '</a>'
|
|
),
|
|
'category' => array(
|
|
'id' => $message['ID_CAT'],
|
|
'name' => $message['cName'],
|
|
'href' => $scripturl . '#' . $message['ID_CAT'],
|
|
'link' => '<a href="' . $scripturl . '#' . $message['ID_CAT'] . '">' . $message['cName'] . '</a>'
|
|
)
|
|
));
|
|
determineTopicClass($output);
|
|
|
|
$body_highlighted = $message['body'];
|
|
$subject_highlighted = $message['subject'];
|
|
|
|
foreach ($context['key_words'] as $query)
|
|
{
|
|
// Fix the international characters in the keyword too.
|
|
# $query = preg_replace('~&#(\d{4,5}|[3-9]\d{2,4}|2[6-9]\d);~', '&#$1;', strtr(preg_quote($query, '/'), array('&' => '&')));
|
|
|
|
$body_highlighted = preg_replace('/((<[^>]*)|' . $query . ')/ieu', "'\$2' == '\$1' ? stripslashes('\$1') : '<b class=\"highlight\">\$1</b>'", $body_highlighted);
|
|
$subject_highlighted = preg_replace('/((<[^>]*)|' . $query . ')/ie', "'$2' == '$1' ? stripslashes('$1') : '<b class=\"highlight\">$1</b>'", $subject_highlighted);
|
|
}
|
|
|
|
$output['matches'][] = array(
|
|
'id' => $message['ID_MSG'],
|
|
'attachment' => loadAttachmentContext($message['ID_MSG']),
|
|
'alternate' => $counter % 2,
|
|
'member' => &$themeUser[$message['ID_MEMBER']],
|
|
'icon' => $message['icon'],
|
|
'subject' => $message['subject'],
|
|
'subject_highlighted' => $subject_highlighted,
|
|
'time' => timeformat($message['posterTime']),
|
|
'timestamp' => $message['posterTime'],
|
|
'counter' => $counter,
|
|
'modified' => array(
|
|
'time' => timeformat($message['modifiedTime']),
|
|
'timestamp' => $message['modifiedTime'],
|
|
'name' => $message['modifiedName']
|
|
),
|
|
'body' => $message['body'],
|
|
'body_highlighted' => $body_highlighted,
|
|
'start' => 'msg' . $message['ID_MSG']
|
|
);
|
|
$counter++;
|
|
|
|
return $output;
|
|
}
|
|
|
|
?>
|