1
0
mirror of https://github.com/flarum/core.git synced 2025-07-26 03:01:22 +02:00

Search API tweaks

Rename some methods, include a mechanism for gambit negation.
Also always include the relevant posts in results. closes
flarum/core#111
This commit is contained in:
Toby Zerner
2015-06-26 12:20:43 +09:30
parent efbe46f7a9
commit f2a28e1185
9 changed files with 39 additions and 23 deletions

View File

@@ -41,11 +41,16 @@ class DiscussionSearcher implements SearcherInterface
$this->defaultSort = $defaultSort; $this->defaultSort = $defaultSort;
} }
public function query() public function getQuery()
{ {
return $this->query->getQuery(); return $this->query->getQuery();
} }
public function getUser()
{
return $this->user;
}
public function addActiveGambit($gambit) public function addActiveGambit($gambit)
{ {
$this->activeGambits[] = $gambit; $this->activeGambits[] = $gambit;
@@ -90,17 +95,17 @@ class DiscussionSearcher implements SearcherInterface
$discussions->pop(); $discussions->pop();
} }
if (in_array('relevantPosts', $load) && count($this->relevantPosts)) { if (in_array('relevantPosts', $load)) {
$load = array_diff($load, ['relevantPosts', 'relevantPosts.discussion', 'relevantPosts.user']); $load = array_diff($load, ['relevantPosts', 'relevantPosts.discussion', 'relevantPosts.user']);
$postIds = []; $postIds = [];
foreach ($this->relevantPosts as $id => $posts) { foreach ($this->relevantPosts as $id => $posts) {
$postIds = array_merge($postIds, array_slice($posts, 0, 2)); $postIds = array_merge($postIds, array_slice($posts, 0, 2));
} }
$posts = $this->posts->findByIds($postIds, $this->user)->load('user'); $posts = $postIds ? $this->posts->findByIds($postIds, $this->user)->load('user')->all() : [];
foreach ($discussions as $discussion) { foreach ($discussions as $discussion) {
$discussion->relevantPosts = $posts->filter(function ($post) use ($discussion) { $discussion->relevantPosts = array_filter($posts, function ($post) use ($discussion) {
return $post->discussion_id == $discussion->id; return $post->discussion_id == $discussion->id;
}); });
} }

View File

@@ -19,12 +19,12 @@ class AuthorGambit extends GambitAbstract
$this->users = $users; $this->users = $users;
} }
public function conditions($matches, SearcherInterface $searcher) protected function conditions(SearcherInterface $searcher, array $matches, $negate)
{ {
$username = trim($matches[1], '"'); $username = trim($matches[1], '"');
$id = $this->users->getIdForUsername($username); $id = $this->users->getIdForUsername($username);
$searcher->query()->where('start_user_id', $id); $searcher->getQuery()->where('start_user_id', $negate ? '!=' : '=', $id);
} }
} }

View File

@@ -2,9 +2,9 @@
use Flarum\Core\Repositories\PostRepositoryInterface; use Flarum\Core\Repositories\PostRepositoryInterface;
use Flarum\Core\Search\SearcherInterface; use Flarum\Core\Search\SearcherInterface;
use Flarum\Core\Search\GambitAbstract; use Flarum\Core\Search\GambitInterface;
class FulltextGambit extends GambitAbstract class FulltextGambit implements GambitInterface
{ {
protected $posts; protected $posts;
@@ -24,7 +24,8 @@ class FulltextGambit extends GambitAbstract
} }
$discussions = array_unique($discussions); $discussions = array_unique($discussions);
$searcher->query()->whereIn('id', $discussions); // TODO: implement negate (match for - at start of string)
$searcher->getQuery()->whereIn('id', $discussions);
$searcher->setDefaultSort(['id' => $discussions]); $searcher->setDefaultSort(['id' => $discussions]);
} }

View File

@@ -10,7 +10,7 @@ class UnreadGambit extends GambitAbstract
* The gambit's regex pattern. * The gambit's regex pattern.
* @var string * @var string
*/ */
protected $pattern = 'unread:(true|false)'; protected $pattern = 'is:unread';
protected $discussions; protected $discussions;
@@ -19,17 +19,17 @@ class UnreadGambit extends GambitAbstract
$this->discussions = $discussions; $this->discussions = $discussions;
} }
protected function conditions($matches, SearcherInterface $searcher) protected function conditions(SearcherInterface $searcher, array $matches, $negate)
{ {
$user = $searcher->user; $user = $searcher->user;
if ($user->exists) { if ($user->exists) {
$readIds = $this->discussions->getReadIds($user); $readIds = $this->discussions->getReadIds($user);
if ($matches[1] === 'true') { if (! $negate) {
$searcher->query()->whereNotIn('id', $readIds)->where('last_time', '>', $user->read_time ?: 0); $searcher->getQuery()->whereNotIn('id', $readIds)->where('last_time', '>', $user->read_time ?: 0);
} else { } else {
$searcher->query()->whereIn('id', $readIds)->orWhere('last_time', '<=', $user->read_time ?: 0); $searcher->getQuery()->whereIn('id', $readIds)->orWhere('last_time', '<=', $user->read_time ?: 0);
} }
} }
} }

View File

@@ -7,15 +7,18 @@ abstract class GambitAbstract
public function apply($bit, SearcherInterface $searcher) public function apply($bit, SearcherInterface $searcher)
{ {
if ($matches = $this->match($bit)) { if ($matches = $this->match($bit)) {
$this->conditions($matches, $searcher); list($negate) = array_splice($matches, 1, 1);
$this->conditions($searcher, $matches, !! $negate);
return true; return true;
} }
} }
public function match($bit) protected function match($bit)
{ {
if (preg_match('/^'.$this->pattern.'$/i', $bit, $matches)) { if (preg_match('/^(-?)'.$this->pattern.'$/i', $bit, $matches)) {
return $matches; return $matches;
} }
} }
abstract protected function conditions(SearcherInterface $searcher, array $matches, $negate);
} }

View File

@@ -2,5 +2,5 @@
interface GambitInterface interface GambitInterface
{ {
public function apply($string, $searcher); public function apply($string, SearcherInterface $searcher);
} }

View File

@@ -2,7 +2,9 @@
interface SearcherInterface interface SearcherInterface
{ {
public function query(); public function getQuery();
public function getUser();
public function setDefaultSort($defaultSort); public function setDefaultSort($defaultSort);
} }

View File

@@ -2,9 +2,9 @@
use Flarum\Core\Repositories\UserRepositoryInterface; use Flarum\Core\Repositories\UserRepositoryInterface;
use Flarum\Core\Search\SearcherInterface; use Flarum\Core\Search\SearcherInterface;
use Flarum\Core\Search\GambitAbstract; use Flarum\Core\Search\GambitInterface;
class FulltextGambit extends GambitAbstract class FulltextGambit implements GambitInterface
{ {
protected $users; protected $users;
@@ -17,7 +17,7 @@ class FulltextGambit extends GambitAbstract
{ {
$users = $this->users->getIdsForUsername($string, $searcher->user); $users = $this->users->getIdsForUsername($string, $searcher->user);
$searcher->query()->whereIn('id', $users); $searcher->getQuery()->whereIn('id', $users);
$searcher->setDefaultSort(['id' => $users]); $searcher->setDefaultSort(['id' => $users]);
} }

View File

@@ -28,11 +28,16 @@ class UserSearcher implements SearcherInterface
$this->defaultSort = $defaultSort; $this->defaultSort = $defaultSort;
} }
public function query() public function getQuery()
{ {
return $this->query->getQuery(); return $this->query->getQuery();
} }
public function getUser()
{
return $this->user;
}
public function addActiveGambit($gambit) public function addActiveGambit($gambit)
{ {
$this->activeGambits[] = $gambit; $this->activeGambits[] = $gambit;