2013-10-28 11:19:15 +01:00
|
|
|
<?php
|
2013-12-18 15:10:53 +01:00
|
|
|
class PostSearchService extends AbstractSearchService
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2013-11-24 21:41:38 +01:00
|
|
|
private static $enableTokenLimit = true;
|
2013-10-28 11:19:15 +01:00
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
public static function getPostIdsAround($searchQuery, $postId)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return Database::transaction(function() use ($searchQuery, $postId)
|
|
|
|
{
|
|
|
|
$stmt = new SqlRawStatement('CREATE TEMPORARY TABLE IF NOT EXISTS post_search(id INTEGER PRIMARY KEY, post_id INTEGER)');
|
|
|
|
Database::exec($stmt);
|
|
|
|
|
|
|
|
$stmt = new SqlDeleteStatement();
|
|
|
|
$stmt->setTable('post_search');
|
|
|
|
Database::exec($stmt);
|
|
|
|
|
|
|
|
$innerStmt = new SqlSelectStatement($searchQuery);
|
|
|
|
$innerStmt->setColumn('id');
|
|
|
|
self::decorate($innerStmt, $searchQuery);
|
|
|
|
$stmt = new SqlInsertStatement();
|
|
|
|
$stmt->setTable('post_search');
|
|
|
|
$stmt->setSource(['post_id'], $innerStmt);
|
|
|
|
Database::exec($stmt);
|
|
|
|
|
|
|
|
$stmt = new SqlSelectStatement();
|
|
|
|
$stmt->setTable('post_search');
|
2014-02-23 10:03:05 +01:00
|
|
|
$stmt->setColumn('id');
|
|
|
|
$stmt->setCriterion(new SqlEqualsOperator('post_id', new SqlBinding($postId)));
|
|
|
|
$rowId = Database::fetchOne($stmt)['id'];
|
2014-02-22 19:21:32 +01:00
|
|
|
|
2014-02-23 10:03:05 +01:00
|
|
|
//it's possible that given post won't show in search results:
|
|
|
|
//it can be hidden, it can have prohibited safety etc.
|
|
|
|
if (!$rowId)
|
2014-02-22 19:21:32 +01:00
|
|
|
return [null, null];
|
2014-02-23 10:03:05 +01:00
|
|
|
|
|
|
|
$rowId = intval($rowId);
|
|
|
|
$stmt->setColumn('post_id');
|
|
|
|
|
|
|
|
$stmt->setCriterion(new SqlEqualsOperator('id', new SqlBinding($rowId - 1)));
|
|
|
|
$nextPostId = Database::fetchOne($stmt)['post_id'];
|
|
|
|
|
|
|
|
$stmt->setCriterion(new SqlEqualsOperator('id', new SqlBinding($rowId + 1)));
|
|
|
|
$prevPostId = Database::fetchOne($stmt)['post_id'];
|
|
|
|
|
|
|
|
return [$prevPostId, $nextPostId];
|
2014-02-22 19:21:32 +01:00
|
|
|
});
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
public static function enableTokenLimit($enable)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
self::$enableTokenLimit = $enable;
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function decorateNegation(SqlExpression $criterion, $negative)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return !$negative
|
|
|
|
? $criterion
|
|
|
|
: new SqlNegationOperator($criterion);
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterUserSafety(SqlSelectStatement $stmt)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
$allowedSafety = PrivilegesHelper::getAllowedSafety();
|
|
|
|
$stmt->getCriterion()->add(SqlInOperator::fromArray('safety', SqlBinding::fromArray($allowedSafety)));
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTag(SqlSelectStatement $stmt, $val, $neg)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2013-12-18 15:10:53 +01:00
|
|
|
$tag = TagModel::findByName($val);
|
2014-02-22 19:21:32 +01:00
|
|
|
$innerStmt = new SqlSelectStatement();
|
|
|
|
$innerStmt->setTable('post_tag');
|
|
|
|
$innerStmt->setCriterion((new SqlConjunction)
|
|
|
|
->add(new SqlEqualsOperator('post_id', 'post.id'))
|
|
|
|
->add(new SqlEqualsOperator('post_tag.tag_id', new SqlBinding($tag->id))));
|
|
|
|
$stmt->getCriterion()->add(self::decorateNegation(new SqlExistsOperator($innerStmt), $neg));
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenId($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
|
|
|
$ids = preg_split('/[;,]/', $val);
|
|
|
|
$ids = array_map('intval', $ids);
|
2014-02-22 19:21:32 +01:00
|
|
|
return SqlInOperator::fromArray('id', $ids);
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenIdMin($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return new SqlEqualsOrGreaterOperator('id', new SqlBinding(intval($val)));
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenIdMax($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return new SqlEqualsOrLesserOperator('id', new SqlBinding(intval($val)));
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenScoreMin($val)
|
2013-11-10 12:23:59 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return new SqlEqualsOrGreaterOperator('score', new SqlBinding(intval($val)));
|
2013-11-10 12:23:59 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenScoreMax($val)
|
2013-11-10 12:23:59 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return new SqlEqualsOrLesserOperator('score', new SqlBinding(intval($val)));
|
2013-11-10 12:23:59 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenTagMin($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return new SqlEqualsOrGreaterOperator('tag_count', new SqlBinding(intval($val)));
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenTagMax($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return new SqlEqualsOrLesserOperator('tag_count', new SqlBinding(intval($val)));
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenFavMin($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return new SqlEqualsOrGreaterOperator('fav_count', new SqlBinding(intval($val)));
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenFavMax($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return new SqlEqualsOrLesserOperator('fav_count', new SqlBinding(intval($val)));
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenCommentMin($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return new SqlEqualsOrGreaterOperator('comment_count', new SqlBinding(intval($val)));
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenCommentMax($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return new SqlEqualsOrLesserOperator('comment_count', new SqlBinding(intval($val)));
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenSpecial($val)
|
2013-11-22 11:15:38 +01:00
|
|
|
{
|
|
|
|
$context = \Chibi\Registry::getContext();
|
|
|
|
|
2014-02-01 09:53:32 +01:00
|
|
|
switch ($val)
|
2013-11-22 11:15:38 +01:00
|
|
|
{
|
|
|
|
case 'liked':
|
|
|
|
case 'likes':
|
2014-02-22 19:21:32 +01:00
|
|
|
$innerStmt = new SqlSelectStatement();
|
|
|
|
$innerStmt->setTable('post_score');
|
|
|
|
$innerStmt->setCriterion((new SqlConjunction)
|
|
|
|
->add(new SqlGreaterOperator('score', '0'))
|
|
|
|
->add(new SqlEqualsOperator('post_id', 'post.id'))
|
|
|
|
->add(new SqlEqualsOperator('user_id', new SqlBinding($context->user->id))));
|
|
|
|
return new SqlExistsOperator($innerStmt);
|
2013-11-22 11:15:38 +01:00
|
|
|
|
|
|
|
case 'disliked':
|
|
|
|
case 'dislikes':
|
2014-02-22 19:21:32 +01:00
|
|
|
$innerStmt = new SqlSelectStatement();
|
|
|
|
$innerStmt->setTable('post_score');
|
|
|
|
$innerStmt->setCriterion((new SqlConjunction)
|
|
|
|
->add(new SqlLesserOperator('score', '0'))
|
|
|
|
->add(new SqlEqualsOperator('post_id', 'post.id'))
|
|
|
|
->add(new SqlEqualsOperator('user_id', new SqlBinding($context->user->id))));
|
|
|
|
return new SqlExistsOperator($innerStmt);
|
2013-11-22 11:15:38 +01:00
|
|
|
|
2014-02-01 09:51:37 +01:00
|
|
|
case 'hidden':
|
2014-02-22 19:21:32 +01:00
|
|
|
return new SqlStringExpression('hidden');
|
2014-02-01 09:51:37 +01:00
|
|
|
|
2013-11-22 11:15:38 +01:00
|
|
|
default:
|
|
|
|
throw new SimpleException('Unknown special "' . $val . '"');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenType($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-01 09:53:32 +01:00
|
|
|
switch ($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
|
|
|
case 'swf':
|
|
|
|
$type = PostType::Flash;
|
|
|
|
break;
|
|
|
|
case 'img':
|
|
|
|
$type = PostType::Image;
|
|
|
|
break;
|
|
|
|
case 'yt':
|
|
|
|
case 'youtube':
|
|
|
|
$type = PostType::Youtube;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw new SimpleException('Unknown type "' . $val . '"');
|
|
|
|
}
|
2014-02-22 19:21:32 +01:00
|
|
|
return new SqlEqualsOperator('type', new SqlBinding($type));
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected static function __filterTokenDateParser($val)
|
|
|
|
{
|
|
|
|
list ($year, $month, $day) = explode('-', $val . '-0-0');
|
|
|
|
$yearMin = $yearMax = intval($year);
|
|
|
|
$monthMin = $monthMax = intval($month);
|
|
|
|
$monthMin = $monthMin ?: 1;
|
|
|
|
$monthMax = $monthMax ?: 12;
|
|
|
|
$dayMin = $dayMax = intval($day);
|
|
|
|
$dayMin = $dayMin ?: 1;
|
|
|
|
$dayMax = $dayMax ?: intval(date('t', mktime(0, 0, 0, $monthMax, 1, $year)));
|
|
|
|
$timeMin = mktime(0, 0, 0, $monthMin, $dayMin, $yearMin);
|
|
|
|
$timeMax = mktime(0, 0, -1, $monthMax, $dayMax+1, $yearMax);
|
|
|
|
return [$timeMin, $timeMax];
|
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenDate($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
|
|
|
list ($timeMin, $timeMax) = self::__filterTokenDateParser($val);
|
2014-02-22 19:21:32 +01:00
|
|
|
return (new SqlConjunction)
|
|
|
|
->add(new SqlEqualsOrGreaterOperator('upload_date', new SqlBinding($timeMin)))
|
|
|
|
->add(new SqlEqualsOrLesserOperator('upload_date', new SqlBinding($timeMax)));
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenDateMin($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
|
|
|
list ($timeMin, $timeMax) = self::__filterTokenDateParser($val);
|
2014-02-22 19:21:32 +01:00
|
|
|
return new SqlEqualsOrGreaterOperator('upload_date', new SqlBinding($timeMin));
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenDateMax($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
|
|
|
list ($timeMin, $timeMax) = self::__filterTokenDateParser($val);
|
2014-02-22 19:21:32 +01:00
|
|
|
return new SqlEqualsOrLesserOperator('upload_date', new SqlBinding($timeMax));
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenFav($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2013-12-18 15:10:53 +01:00
|
|
|
$user = UserModel::findByNameOrEmail($val);
|
2014-02-22 19:21:32 +01:00
|
|
|
$innerStmt = (new SqlSelectStatement)
|
|
|
|
->setTable('favoritee')
|
|
|
|
->setCriterion((new SqlConjunction)
|
|
|
|
->add(new SqlEqualsOperator('post_id', 'post.id'))
|
|
|
|
->add(new SqlEqualsOperator('favoritee.user_id', new SqlBinding($user->id))));
|
|
|
|
return new SqlExistsOperator($innerStmt);
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenFavs($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return self::filterTokenFav($val);
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenComment($val)
|
2013-11-21 14:13:26 +01:00
|
|
|
{
|
2013-12-18 15:10:53 +01:00
|
|
|
$user = UserModel::findByNameOrEmail($val);
|
2014-02-22 19:21:32 +01:00
|
|
|
$innerStmt = (new SqlSelectStatement)
|
|
|
|
->setTable('comment')
|
|
|
|
->setCriterion((new SqlConjunction)
|
|
|
|
->add(new SqlEqualsOperator('post_id', 'post.id'))
|
|
|
|
->add(new SqlEqualsOperator('commenter_id', new SqlBinding($user->id))));
|
|
|
|
return new SqlExistsOperator($innerStmt);
|
2013-11-21 14:13:26 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenCommenter($val)
|
2013-11-21 14:13:26 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return self::filterTokenComment($searchContext, $stmt, $val);
|
2013-11-21 14:13:26 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenSubmit($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2013-12-18 15:10:53 +01:00
|
|
|
$user = UserModel::findByNameOrEmail($val);
|
2014-02-22 19:21:32 +01:00
|
|
|
return new SqlEqualsOperator('uploader_id', new SqlBinding($user->id));
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenUploader($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return self::filterTokenSubmit($val);
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenUpload($val)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return self::filterTokenSubmit($val);
|
2013-11-24 21:41:38 +01:00
|
|
|
}
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function filterTokenUploaded($val)
|
2013-11-24 21:41:38 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
return self::filterTokenSubmit($val);
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
protected static function changeOrder($stmt, $val, $neg = true)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
|
|
|
$randomReset = true;
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
$orderDir = SqlSelectStatement::ORDER_DESC;
|
2013-10-28 11:19:15 +01:00
|
|
|
if (substr($val, -4) == 'desc')
|
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
$orderDir = SqlSelectStatement::ORDER_DESC;
|
2013-10-28 11:19:15 +01:00
|
|
|
$val = rtrim(substr($val, 0, -4), ',');
|
|
|
|
}
|
|
|
|
elseif (substr($val, -3) == 'asc')
|
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
$orderDir = SqlSelectStatement::ORDER_ASC;
|
2013-10-28 11:19:15 +01:00
|
|
|
$val = rtrim(substr($val, 0, -3), ',');
|
|
|
|
}
|
2014-02-22 19:21:32 +01:00
|
|
|
if ($neg)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
$orderDir = $orderDir == SqlSelectStatement::ORDER_DESC
|
|
|
|
? SqlSelectStatement::ORDER_ASC
|
|
|
|
: SqlSelectStatement::ORDER_DESC;
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
switch ($val)
|
|
|
|
{
|
|
|
|
case 'id':
|
2013-11-24 21:41:38 +01:00
|
|
|
$orderColumn = 'id';
|
2013-10-28 11:19:15 +01:00
|
|
|
break;
|
|
|
|
case 'date':
|
2013-11-24 21:41:38 +01:00
|
|
|
$orderColumn = 'upload_date';
|
2013-10-28 11:19:15 +01:00
|
|
|
break;
|
|
|
|
case 'comment':
|
|
|
|
case 'comments':
|
|
|
|
case 'commentcount':
|
2014-02-22 19:21:32 +01:00
|
|
|
case 'comment_count':
|
2013-10-28 11:19:15 +01:00
|
|
|
$orderColumn = 'comment_count';
|
|
|
|
break;
|
|
|
|
case 'fav':
|
|
|
|
case 'favs':
|
|
|
|
case 'favcount':
|
2014-02-22 19:21:32 +01:00
|
|
|
case 'fav_count':
|
2013-10-28 11:19:15 +01:00
|
|
|
$orderColumn = 'fav_count';
|
|
|
|
break;
|
2013-11-10 12:23:59 +01:00
|
|
|
case 'score':
|
|
|
|
$orderColumn = 'score';
|
|
|
|
break;
|
2013-10-28 11:19:15 +01:00
|
|
|
case 'tag':
|
|
|
|
case 'tags':
|
|
|
|
case 'tagcount':
|
2014-02-22 19:21:32 +01:00
|
|
|
case 'tag_count':
|
2013-10-28 11:19:15 +01:00
|
|
|
$orderColumn = 'tag_count';
|
|
|
|
break;
|
|
|
|
case 'random':
|
|
|
|
//seeding works like this: if you visit anything
|
|
|
|
//that triggers order other than random, the seed
|
|
|
|
//is going to reset. however, it stays the same as
|
|
|
|
//long as you keep visiting pages with order:random
|
|
|
|
//specified.
|
|
|
|
$randomReset = false;
|
|
|
|
if (!isset($_SESSION['browsing-seed']))
|
|
|
|
$_SESSION['browsing-seed'] = mt_rand();
|
|
|
|
$seed = $_SESSION['browsing-seed'];
|
|
|
|
$orderColumn = 'SUBSTR(id * ' . $seed .', LENGTH(id) + 2)';
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw new SimpleException('Unknown key "' . $val . '"');
|
|
|
|
}
|
|
|
|
|
2013-10-30 22:38:59 +01:00
|
|
|
if ($randomReset and isset($_SESSION['browsing-seed']))
|
2013-10-28 11:19:15 +01:00
|
|
|
unset($_SESSION['browsing-seed']);
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
$stmt->setOrderBy($orderColumn, $orderDir);
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
public static function decorate(SqlSelectStatement $stmt, $searchQuery)
|
2013-11-24 21:41:38 +01:00
|
|
|
{
|
|
|
|
$config = \Chibi\Registry::getConfig();
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
$stmt->setTable('post');
|
|
|
|
$stmt->setCriterion(new SqlConjunction());
|
2013-11-24 21:41:38 +01:00
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
self::filterUserSafety($stmt);
|
2013-11-24 21:41:38 +01:00
|
|
|
|
|
|
|
/* query tokens */
|
2014-02-22 19:21:32 +01:00
|
|
|
$tokens = array_filter(array_unique(preg_split('/\s+/', strtolower($searchQuery))));
|
2013-11-24 21:41:38 +01:00
|
|
|
if (self::$enableTokenLimit and count($tokens) > $config->browsing->maxSearchTokens)
|
|
|
|
throw new SimpleException('Too many search tokens (maximum: ' . $config->browsing->maxSearchTokens . ')');
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
if (\Chibi\Registry::getContext()->user->hasEnabledHidingDislikedPosts() and !in_array('special:disliked', $tokens))
|
2013-12-05 22:19:21 +01:00
|
|
|
$tokens []= '-special:disliked';
|
2014-02-01 09:51:37 +01:00
|
|
|
if (!PrivilegesHelper::confirm(Privilege::ListPosts, 'hidden') or !in_array('special:hidden', $tokens))
|
|
|
|
$tokens []= '-special:hidden';
|
2013-10-28 11:19:15 +01:00
|
|
|
|
2013-12-05 22:19:21 +01:00
|
|
|
$searchContext = new StdClass;
|
|
|
|
$searchContext->orderColumn = 'id';
|
|
|
|
$searchContext->orderDir = 1;
|
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
foreach ($tokens as $token)
|
2013-11-24 21:41:38 +01:00
|
|
|
{
|
2014-02-22 19:21:32 +01:00
|
|
|
$neg = false;
|
|
|
|
if ($token{0} == '-')
|
|
|
|
{
|
|
|
|
$neg = true;
|
|
|
|
$token = substr($token, 1);
|
|
|
|
}
|
2013-11-24 21:41:38 +01:00
|
|
|
|
2014-02-22 19:21:32 +01:00
|
|
|
if (strpos($token, ':') !== false)
|
|
|
|
{
|
|
|
|
list ($key, $val) = explode(':', $token);
|
|
|
|
$key = strtolower($key);
|
|
|
|
if ($key == 'order')
|
|
|
|
{
|
|
|
|
self::changeOrder($stmt, $val, $neg);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$methodName = 'filterToken' . TextHelper::kebabCaseToCamelCase($key);
|
|
|
|
if (!method_exists(__CLASS__, $methodName))
|
|
|
|
throw new SimpleException('Unknown search token "' . $key . '"');
|
|
|
|
|
|
|
|
$criterion = self::$methodName($val);
|
|
|
|
$criterion = self::decorateNegation($criterion, $neg);
|
|
|
|
$stmt->getCriterion()->add($criterion);
|
|
|
|
}
|
|
|
|
}
|
2013-11-30 19:07:39 +01:00
|
|
|
else
|
2014-02-22 19:21:32 +01:00
|
|
|
{
|
|
|
|
self::filterTag($stmt, $token, $neg);
|
|
|
|
}
|
2013-11-30 19:07:39 +01:00
|
|
|
}
|
2014-02-22 19:21:32 +01:00
|
|
|
|
|
|
|
$stmt->addOrderBy('id',
|
|
|
|
empty($stmt->getOrderBy())
|
|
|
|
? SqlSelectStatement::ORDER_DESC
|
|
|
|
: $stmt->getOrderBy()[0][1]);
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
}
|