-
Notifications
You must be signed in to change notification settings - Fork 431
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #189 from lincanbin/develop
Advanced search #188
- Loading branch information
Showing
8 changed files
with
262 additions
and
183 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,104 +1,168 @@ | ||
<?php | ||
define('FullTableScanTopicLimit', 50000);//当全站主题数量小于该值将会使用更消耗资源的全表扫描搜索 | ||
require(__DIR__ . '/common.php'); | ||
require(__DIR__ . '/language/' . ForumLanguage . '/home.php'); | ||
include __DIR__ . '/'. 'includes/SearchClient.class.php' ; | ||
|
||
$Page = Request('Get', 'page'); | ||
$Keyword = Request('Get', 'keyword'); | ||
$KeywordArray = explode(" ", $Keyword); | ||
$KeywordNum = count($KeywordArray); | ||
$Error = ''; | ||
if(!$KeywordNum){ | ||
AlertMsg('404 Not Found', '404 Not Found', 404); | ||
} | ||
if ($Page < 0 || $Page == 1) | ||
Redirect('search/' . $Keyword); | ||
if ($Page == 0) | ||
$Page = 1; | ||
|
||
$limitSize = 30; | ||
|
||
//如果定义了搜索服务器,就走搜索服务 | ||
if( defined('SearchServer') && SearchServer ) { | ||
try { | ||
$finds = SearchClient::searchLike( $Keyword, 'PostsIndexes' //关键字及索引 | ||
, ($Page-1)*$limitSize, $limitSize //页码 | ||
, ""//过滤条件 | ||
, 'PostTime desc' //排序规则 | ||
); | ||
if ( !empty($finds) ) { | ||
$num = $finds[1]; | ||
$postIds = isset( $finds[0]['id'] ) ?$finds[0]['id']: null; | ||
if( count($postIds ) > 0 ) { | ||
$TopicsArray = $DB->query('SELECT t.`ID`, `Topic`, `Tags`, t.`UserID`, t.`UserName`, t.`LastName`, `LastTime`, `Replies` | ||
, p.Content, p.ID as pID, p.PostTime | ||
FROM ' . PREFIX . 'topics t, '. PREFIX . 'posts p | ||
WHERE t.ID=p.TopicID and p.ID in (?) and t.IsDel=0 | ||
ORDER BY p.PostTime DESC', | ||
$postIds); | ||
foreach( $TopicsArray as &$row ) { | ||
$excerpts = SearchClient::callProxy( 'buildExcerpts', array( | ||
array($row['Topic'], $row['Content']), 'PostsIndexes' | ||
, $Keyword, array( | ||
"before_match" => '<span class="search-keyword">', | ||
"after_match"=> "</span>" ) ) ); | ||
$row['MinContent'] = $excerpts[1]; | ||
} | ||
} | ||
} | ||
}catch( Exception $e ) { | ||
$Error = $e->getMessage(); | ||
} | ||
} else { | ||
//if($CurUserID && $Config['NumTopics'] <= FullTableScanTopicLimit){ | ||
if($Config['NumTopics'] <= FullTableScanTopicLimit){ | ||
$QueryString = str_repeat('or Topic LIKE ? or Tags LIKE ? ', $KeywordNum-1); | ||
$SQLKeywordArray = array(); | ||
foreach ($KeywordArray as $Value) { | ||
$SQLKeywordArray[] = '%'.$Value.'%'; | ||
$SQLKeywordArray[] = '%'.$Value.'%'; | ||
} | ||
$TopicsArray = $DB->query('SELECT `ID`, `Topic`, `Tags`, `UserID`, `UserName`, `LastName`, `LastTime`, `Replies` FROM ' . PREFIX . 'topics | ||
WHERE Topic LIKE ? or Tags LIKE ? '.$QueryString.' | ||
ORDER BY LastTime DESC | ||
LIMIT ' . ($Page - 1) * $Config['TopicsPerPage'] . ',' . $Config['TopicsPerPage'], | ||
$SQLKeywordArray | ||
); | ||
}else{ | ||
$QueryString = str_repeat('or Name LIKE ? ', $KeywordNum-1); | ||
$SQLKeywordArray = array(); | ||
foreach ($KeywordArray as $Value) { | ||
$SQLKeywordArray[] = '%'.$Value.'%'; | ||
} | ||
$TagIDList = $DB->column('SELECT ID FROM ' . PREFIX . 'tags | ||
WHERE Name like ? '.$QueryString, | ||
$SQLKeywordArray | ||
); | ||
if (!$TagIDList) | ||
AlertMsg('404 Not Found', '404 Not Found'); | ||
$TagIDArray = $DB->column('SELECT TopicID FROM ' . PREFIX . 'posttags | ||
WHERE TagID in (?) | ||
ORDER BY TopicID DESC | ||
LIMIT ' . ($Page - 1) * $Config['TopicsPerPage'] . ',' . $Config['TopicsPerPage'], | ||
$TagIDList); | ||
$TopicsArray = array(); | ||
if($TagIDArray){ | ||
$TopicsArray = $DB->query('SELECT `ID`, `Topic`, `Tags`, `UserID`, `UserName`, `LastName`, `LastTime`, `Replies` FROM ' . PREFIX . 'topics | ||
force index(PRI) | ||
WHERE ID in (?) and IsDel=0 | ||
ORDER BY LastTime DESC', | ||
$TagIDArray); | ||
} | ||
} | ||
} | ||
/* | ||
if($Page == 1 && !$TopicsArray){ | ||
AlertMsg('404 Not Found', '404 Not Found', 404); | ||
} | ||
*/ | ||
$DB->CloseConnection(); | ||
$PageTitle = $Lang['Search'].' '.$Keyword.' '; | ||
$PageTitle .= $Page > 1 ? ' Page' . $Page : ''; | ||
$ContentFile = $TemplatePath . 'search.php'; | ||
include($TemplatePath . 'layout.php'); | ||
<?php | ||
require(__DIR__ . '/common.php'); | ||
require(__DIR__ . '/language/' . ForumLanguage . '/home.php'); | ||
include __DIR__ . '/includes/SearchClient.class.php'; | ||
|
||
$Page = Request('Get', 'page'); | ||
$Keyword = Request('Get', 'keyword'); | ||
$KeywordArray = array_unique(explode(" ", $Keyword)); | ||
$Error = ''; | ||
|
||
$PostsSearch = false;//是否启用帖子搜索 | ||
$PostsSearchOffset = array_search('post:true', $KeywordArray); | ||
if ($PostsSearchOffset !== false) { | ||
$PostsSearch = true; | ||
unset($KeywordArray[$PostsSearchOffset]); | ||
} | ||
ksort($KeywordArray); | ||
|
||
if (!$KeywordArray) { | ||
AlertMsg('404 Not Found', '404 Not Found', 404); | ||
} | ||
if ($Page < 0 || $Page == 1) | ||
Redirect('search/' . $Keyword); | ||
if ($Page == 0) | ||
$Page = 1; | ||
|
||
$SQLKeywordArray = array();//查询关键字参数数组 | ||
$AdvancedSearch = false; | ||
$NormalQuery = array();//普通查询条件,用OR连接 | ||
$AdvancedQuery = array();//高级查询条件,用AND连接 | ||
//关键词预处理 | ||
foreach ($KeywordArray as $Key => $KeywordToken) { | ||
//匹配用户名限制条件 | ||
preg_match('/user:(.*)/i', $KeywordToken, $SearchUserTopics); | ||
if (!empty($SearchUserTopics[1]) && IsName($SearchUserTopics[1])){ | ||
$AdvancedSearch = true; | ||
break; | ||
} | ||
} | ||
|
||
// 禁止普通用户使用无索引的全文搜索 | ||
if (!$AdvancedSearch && $CurUserRole < 2) { | ||
$PostsSearch = false; | ||
} | ||
foreach ($KeywordArray as $Key => $KeywordToken) { | ||
//匹配用户名限制条件 | ||
preg_match('/user:(.*)/i', $KeywordToken, $SearchUserTopics); | ||
if (!empty($SearchUserTopics[1]) && IsName($SearchUserTopics[1])){ | ||
if ($PostsSearch) { | ||
$AdvancedQuery[] = 'p.UserName = :PostUser'; | ||
$SQLKeywordArray['PostUser'] = $SearchUserTopics[1]; | ||
} else { | ||
$AdvancedQuery[] = 't.UserName = :TopicUser'; | ||
$SQLKeywordArray['TopicUser'] = $SearchUserTopics[1]; | ||
} | ||
} else { | ||
$ParamName = substr(md5($KeywordToken), 0, 8); | ||
if ($PostsSearch) { | ||
$NormalQuery[] = 'p.Subject LIKE :Subject' . $ParamName . ' or p.Content LIKE :Content' . $ParamName; | ||
$SQLKeywordArray['Subject' . $ParamName] = '%' . $KeywordToken . '%'; | ||
$SQLKeywordArray['Content' . $ParamName] = '%' . $KeywordToken . '%'; | ||
} else { | ||
$NormalQuery[] = 't.Topic LIKE :Topic' . $ParamName . ' or t.Tags LIKE :Tag' . $ParamName; | ||
$SQLKeywordArray['Topic' . $ParamName] = '%' . $KeywordToken . '%'; | ||
$SQLKeywordArray['Tag' . $ParamName] = '%' . $KeywordToken . '%'; | ||
} | ||
} | ||
} | ||
|
||
$SearchCondition = array(); | ||
$Temp = implode(' AND ', $AdvancedQuery); | ||
if (!empty($Temp)) { | ||
$SearchCondition[] = $Temp; | ||
} | ||
$Temp = implode(' OR ', $NormalQuery); | ||
if (!empty($Temp)) { | ||
$SearchCondition[] = '(' . $Temp . ')'; | ||
} | ||
unset($Temp); | ||
$SearchConditionQuery = implode(' AND ', $SearchCondition); | ||
|
||
//如果定义了搜索服务器,并且不是高级搜索,就走搜索服务 | ||
if (defined('SearchServer') && SearchServer && !$AdvancedSearch) { | ||
try { | ||
$finds = SearchClient::searchLike($Keyword, 'PostsIndexes' //关键字及索引 | ||
, ($Page - 1) * $Config['TopicsPerPage'], $Config['TopicsPerPage'] | ||
, "" //过滤条件 | ||
, 'PostTime desc' //排序规则 | ||
); | ||
if (!empty($finds)) { | ||
$num = $finds[1]; | ||
$PostIdList = isset($finds[0]['id']) ? $finds[0]['id'] : null; | ||
if (count($PostIdList) > 0) { | ||
$TopicsArray = $DB->query('SELECT | ||
t.`ID`, | ||
t.`Topic`, | ||
t.`Tags`, | ||
t.`LastName`, | ||
t.`Replies`, | ||
p.`UserID`, | ||
p.`UserName`, | ||
p.`Content`, | ||
p.`ID` AS PostID, | ||
p.`PostTime` AS LastTime | ||
FROM ' . PREFIX . 'topics t, ' . PREFIX . 'posts p | ||
WHERE t.ID=p.TopicID and p.ID in (?) and t.IsDel=0 | ||
ORDER BY p.PostTime DESC', $PostIdList); | ||
foreach ($TopicsArray as &$row) { | ||
$excerpts = SearchClient::callProxy('buildExcerpts', array( | ||
array( | ||
$row['Topic'], | ||
$row['Content'] | ||
), | ||
'PostsIndexes', | ||
$Keyword, | ||
array( | ||
"before_match" => '<span class="search-keyword">', | ||
"after_match" => "</span>" | ||
) | ||
)); | ||
$row['MinContent'] = $excerpts[1]; | ||
} | ||
} | ||
} | ||
} | ||
catch (Exception $e) { | ||
$Error = $e->getMessage(); | ||
} | ||
} else { | ||
if ($PostsSearch) { | ||
$SearchFields = 'SELECT | ||
t.`ID`, | ||
t.`Topic`, | ||
t.`Tags`, | ||
t.`LastName`, | ||
t.`Replies`, | ||
p.`UserID`, | ||
p.`UserName`, | ||
p.`Content`, | ||
p.`ID` AS PostID, | ||
p.`PostTime` AS LastTime | ||
FROM ' . PREFIX . 'posts p | ||
LEFT JOIN ' . PREFIX . 'topics t | ||
ON t.ID=p.TopicID'; | ||
} else { | ||
$SearchFields = 'SELECT t.`ID`, t.`Topic`, t.`Tags`, t.`UserID`, t.`UserName`, t.`LastName`, t.`LastTime`, t.`Replies` | ||
FROM ' . PREFIX . 'topics t '; | ||
} | ||
$TopicsArray = $DB->query($SearchFields . ' | ||
WHERE ' . $SearchConditionQuery . ' | ||
ORDER BY LastTime DESC | ||
LIMIT ' . ($Page - 1) * $Config['TopicsPerPage'] . ', ' . $Config['TopicsPerPage'], $SQLKeywordArray); | ||
if ($PostsSearch) { | ||
foreach ($TopicsArray as &$Topic) { | ||
$Topic['MinContent'] = strip_tags(mb_substr($Topic['Content'], 0, 300, 'utf-8'),'<p><br>'); | ||
} | ||
} | ||
} | ||
/* | ||
if($Page == 1 && !$TopicsArray){ | ||
AlertMsg('404 Not Found', '404 Not Found', 404); | ||
} | ||
*/ | ||
$DB->CloseConnection(); | ||
$PageTitle = $Lang['Search'] . ' ' . $Keyword . ' '; | ||
$PageTitle .= $Page > 1 ? ' Page' . $Page : ''; | ||
$ContentFile = $TemplatePath . 'search.php'; | ||
include($TemplatePath . 'layout.php'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.