Файл: library/XenForo/Search/DataHandler/Post.php
Строк: 401
<?php
/**
* Handles searching of posts.
*
* @package XenForo_Search
*/
class XenForo_Search_DataHandler_Post extends XenForo_Search_DataHandler_Abstract
{
/**
* @var XenForo_Model_Post
*/
protected $_postModel = null;
/**
* @var XenForo_Model_Thread
*/
protected $_threadModel = null;
/**
* Inserts into (or replaces a record) in the index.
*
* @see XenForo_Search_DataHandler_Abstract::_insertIntoIndex()
*/
protected function _insertIntoIndex(XenForo_Search_Indexer $indexer, array $data, array $parentData = null)
{
if ($data['message_state'] != 'visible')
{
return;
}
$metadata = array();
$title = '';
if ($parentData)
{
$thread = $parentData;
if ($thread['discussion_state'] != 'visible')
{
return;
}
if ($data['post_id'] == $thread['first_post_id'] || $thread['first_post_id'] === 0)
{
$title = $thread['title'];
if (!empty($thread['prefix_id']))
{
$metadata['prefix'] = $thread['prefix_id'];
}
}
$metadata['node'] = $thread['node_id'];
}
$metadata['thread'] = $data['thread_id'];
$indexer->insertIntoIndex(
'post', $data['post_id'],
$title, $data['message'],
$data['post_date'], $data['user_id'], $data['thread_id'], $metadata
);
}
/**
* Updates a record in the index.
*
* @see XenForo_Search_DataHandler_Abstract::_updateIndex()
*/
protected function _updateIndex(XenForo_Search_Indexer $indexer, array $data, array $fieldUpdates)
{
$indexer->updateIndex('post', $data['post_id'], $fieldUpdates);
}
/**
* Deletes one or more records from the index.
*
* @see XenForo_Search_DataHandler_Abstract::_deleteFromIndex()
*/
protected function _deleteFromIndex(XenForo_Search_Indexer $indexer, array $dataList)
{
$postIds = array();
foreach ($dataList AS $data)
{
$postIds[] = is_array($data) ? $data['post_id'] : $data;
}
$indexer->deleteFromIndex('post', $postIds);
}
/**
* Rebuilds the index for a batch.
*
* @see XenForo_Search_DataHandler_Abstract::rebuildIndex()
*/
public function rebuildIndex(XenForo_Search_Indexer $indexer, $lastId, $batchSize)
{
$postIds = $this->_getPostModel()->getPostIdsInRange($lastId, $batchSize);
if (!$postIds)
{
return false;
}
$this->quickIndex($indexer, $postIds);
return max($postIds);
}
/**
* Rebuilds the index for the specified content.
* @see XenForo_Search_DataHandler_Abstract::quickIndex()
*/
public function quickIndex(XenForo_Search_Indexer $indexer, array $contentIds)
{
$posts = $this->_getPostModel()->getPostsByIds($contentIds);
$threadIds = array();
foreach ($posts AS $post)
{
$threadIds[] = $post['thread_id'];
}
$threads = $this->_getThreadModel()->getThreadsByIds(array_unique($threadIds));
foreach ($posts AS $post)
{
$thread = (isset($threads[$post['thread_id']]) ? $threads[$post['thread_id']] : null);
if (!$thread)
{
continue;
}
$this->insertIntoIndex($indexer, $post, $thread);
}
return true;
}
/**
* Gets the type-specific data for a collection of results of this content type.
*
* @see XenForo_Search_DataHandler_Abstract::getDataForResults()
*/
public function getDataForResults(array $ids, array $viewingUser, array $resultsGrouped)
{
$postModel = $this->_getPostModel();
$posts = $postModel->getPostsByIds($ids, array(
'join' => XenForo_Model_Post::FETCH_THREAD | XenForo_Model_Post::FETCH_FORUM | XenForo_Model_Post::FETCH_USER,
'permissionCombinationId' => $viewingUser['permission_combination_id']
));
$posts = $postModel->unserializePermissionsInList($posts, 'node_permission_cache');
foreach ($posts AS $postId => $post)
{
if ($post['post_id'] == $post['first_post_id'] && isset($resultsGrouped['thread'][$post['thread_id']]))
{
// matched first post and thread, skip the post
unset($posts[$postId]);
}
}
return $posts;
}
/**
* Determines if this result is viewable.
*
* @see XenForo_Search_DataHandler_Abstract::canViewResult()
*/
public function canViewResult(array $result, array $viewingUser)
{
return $this->_getPostModel()->canViewPostAndContainer(
$result, $result, $result, $null, $result['permissions'], $viewingUser
);
}
/**
* Prepares a result for display.
*
* @see XenForo_Search_DataHandler_Abstract::prepareResult()
*/
public function prepareResult(array $result, array $viewingUser)
{
$result = $this->_getPostModel()->preparePost($result, $result, $result, $result['permissions'], $viewingUser);
$result['title'] = XenForo_Helper_String::censorString($result['title']);
return $result;
}
/**
* Gets the date of the result (from the result's content).
*
* @see XenForo_Search_DataHandler_Abstract::getResultDate()
*/
public function getResultDate(array $result)
{
return $result['post_date'];
}
/**
* Renders a result to HTML.
*
* @see XenForo_Search_DataHandler_Abstract::renderResult()
*/
public function renderResult(XenForo_View $view, array $result, array $search)
{
return $view->createTemplateObject('search_result_post', array(
'post' => $result,
'thread' => $result,
'forum' => array(
'node_id' => $result['node_id'],
'title' => $result['node_title'],
'node_name' => $result['node_name']
),
'search' => $search
));
}
/**
* Gets the content types searched in a type-specific search.
*
* @see XenForo_Search_DataHandler_Abstract::getSearchContentTypes()
*/
public function getSearchContentTypes()
{
return array('post', 'thread');
}
/**
* Get type-specific constraints from input.
*
* @param XenForo_Input $input
*
* @return array
*/
public function getTypeConstraintsFromInput(XenForo_Input $input)
{
$constraints = array();
$replyCount = $input->filterSingle('reply_count', XenForo_Input::UINT);
if ($replyCount)
{
$constraints['reply_count'] = $replyCount;
}
$prefixes = $input->filterSingle('prefixes', XenForo_Input::UINT, array('array' => true));
if ($prefixes && reset($prefixes))
{
$prefixes = array_unique($prefixes);
$constraints['prefix'] = implode(' ', $prefixes);
if (!$constraints['prefix'])
{
unset($constraints['prefix']); // just 0
}
}
$threadId = $input->filterSingle('thread_id', XenForo_Input::UINT);
if ($threadId)
{
$constraints['thread'] = $threadId;
// undo things that don't make sense with this
$constraints['titles_only'] = false;
}
return $constraints;
}
/**
* Process a type-specific constraint.
*
* @see XenForo_Search_DataHandler_Abstract::processConstraint()
*/
public function processConstraint(XenForo_Search_SourceHandler_Abstract $sourceHandler, $constraint, $constraintInfo, array $constraints)
{
switch ($constraint)
{
case 'reply_count':
$replyCount = intval($constraintInfo);
if ($replyCount > 0)
{
return array(
'query' => array('thread', 'reply_count', '>=', $replyCount)
);
}
case 'prefix':
if ($constraintInfo)
{
return array(
'metadata' => array('prefix', preg_split('/D+/', strval($constraintInfo))),
);
}
case 'thread':
$threadId = intval($constraintInfo);
if ($threadId > 0)
{
return array(
'metadata' => array('thread', $threadId)
);
}
}
return false;
}
/**
* Gets the search form controller response for this type.
*
* @see XenForo_Search_DataHandler_Abstract::getSearchFormControllerResponse()
*/
public function getSearchFormControllerResponse(XenForo_ControllerPublic_Abstract $controller, XenForo_Input $input, array $viewParams)
{
$params = $input->filterSingle('c', XenForo_Input::ARRAY_SIMPLE);
$viewParams['search']['reply_count'] = empty($params['reply_count']) ? '' : $params['reply_count'];
if (!empty($params['prefix']))
{
$viewParams['search']['prefixes'] = array_fill_keys(explode(' ', $params['prefix']), true);
}
else
{
$viewParams['search']['prefixes'] = array();
}
/** @var $threadPrefixModel XenForo_Model_ThreadPrefix */
$threadPrefixModel = XenForo_Model::create('XenForo_Model_ThreadPrefix');
$viewParams['prefixes'] = $threadPrefixModel->getPrefixesByGroups();
if ($viewParams['prefixes'])
{
$visiblePrefixes = $threadPrefixModel->getVisiblePrefixIds();
foreach ($viewParams['prefixes'] AS $key => &$prefixes)
{
foreach ($prefixes AS $prefixId => $prefix)
{
if (!isset($visiblePrefixes[$prefixId]))
{
unset($prefixes[$prefixId]);
}
}
if (!count($prefixes))
{
unset($viewParams['prefixes'][$key]);
}
}
}
$viewParams['search']['thread'] = array();
if (!empty($params['thread']))
{
$threadModel = $this->_getThreadModel();
$thread = $threadModel->getThreadById($params['thread'], array(
'join' => XenForo_Model_Thread::FETCH_FORUM,
'permissionCombinationId' => XenForo_Visitor::getPermissionCombinationId(),
));
if ($thread)
{
$permissions = XenForo_Permission::unserializePermissions($thread['node_permission_cache']);
if ($threadModel->canViewThreadAndContainer($thread, $thread, $null, $permissions))
{
$viewParams['search']['thread'] = $this->_getThreadModel()->getThreadById($params['thread']);
}
}
}
return $controller->responseView('XenForo_ViewPublic_Search_Form_Post', 'search_form_post', $viewParams);
}
/**
* Gets the search order for a type-specific search.
*
* @see XenForo_Search_DataHandler_Abstract::getOrderClause()
*/
public function getOrderClause($order)
{
if ($order == 'replies')
{
return array(
array('thread', 'reply_count', 'desc'),
array('search_index', 'item_date', 'desc')
);
}
return false;
}
/**
* Gets the necessary join structure information for this type.
*
* @see XenForo_Search_DataHandler_Abstract::getJoinStructures()
*/
public function getJoinStructures(array $tables)
{
$structures = array();
if (isset($tables['thread']))
{
$structures['thread'] = array(
'table' => 'xf_thread',
'key' => 'thread_id',
'relationship' => array('search_index', 'discussion_id'),
);
}
return $structures;
}
/**
* Gets the content type that will be used when grouping for this type.
*
* @see XenForo_Search_DataHandler_Abstract::getGroupByType()
*/
public function getGroupByType()
{
return 'thread';
}
/**
* @return XenForo_Model_Post
*/
protected function _getPostModel()
{
if (!$this->_postModel)
{
$this->_postModel = XenForo_Model::create('XenForo_Model_Post');
}
return $this->_postModel;
}
/**
* @return XenForo_Model_Thread
*/
protected function _getThreadModel()
{
if (!$this->_threadModel)
{
$this->_threadModel = XenForo_Model::create('XenForo_Model_Thread');
}
return $this->_threadModel;
}
}