From f2a28e11858e655361ec619a4d614126146d0a68 Mon Sep 17 00:00:00 2001 From: Toby Zerner Date: Fri, 26 Jun 2015 12:20:43 +0930 Subject: [PATCH] Search API tweaks Rename some methods, include a mechanism for gambit negation. Also always include the relevant posts in results. closes flarum/core#111 --- .../Core/Search/Discussions/DiscussionSearcher.php | 13 +++++++++---- .../Search/Discussions/Gambits/AuthorGambit.php | 4 ++-- .../Search/Discussions/Gambits/FulltextGambit.php | 7 ++++--- .../Search/Discussions/Gambits/UnreadGambit.php | 10 +++++----- framework/core/src/Core/Search/GambitAbstract.php | 9 ++++++--- framework/core/src/Core/Search/GambitInterface.php | 2 +- .../core/src/Core/Search/SearcherInterface.php | 4 +++- .../Core/Search/Users/Gambits/FulltextGambit.php | 6 +++--- .../core/src/Core/Search/Users/UserSearcher.php | 7 ++++++- 9 files changed, 39 insertions(+), 23 deletions(-) diff --git a/framework/core/src/Core/Search/Discussions/DiscussionSearcher.php b/framework/core/src/Core/Search/Discussions/DiscussionSearcher.php index 81e1fbfd5..79db52405 100644 --- a/framework/core/src/Core/Search/Discussions/DiscussionSearcher.php +++ b/framework/core/src/Core/Search/Discussions/DiscussionSearcher.php @@ -41,11 +41,16 @@ class DiscussionSearcher implements SearcherInterface $this->defaultSort = $defaultSort; } - public function query() + public function getQuery() { return $this->query->getQuery(); } + public function getUser() + { + return $this->user; + } + public function addActiveGambit($gambit) { $this->activeGambits[] = $gambit; @@ -90,17 +95,17 @@ class DiscussionSearcher implements SearcherInterface $discussions->pop(); } - if (in_array('relevantPosts', $load) && count($this->relevantPosts)) { + if (in_array('relevantPosts', $load)) { $load = array_diff($load, ['relevantPosts', 'relevantPosts.discussion', 'relevantPosts.user']); $postIds = []; foreach ($this->relevantPosts as $id => $posts) { $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) { - $discussion->relevantPosts = $posts->filter(function ($post) use ($discussion) { + $discussion->relevantPosts = array_filter($posts, function ($post) use ($discussion) { return $post->discussion_id == $discussion->id; }); } diff --git a/framework/core/src/Core/Search/Discussions/Gambits/AuthorGambit.php b/framework/core/src/Core/Search/Discussions/Gambits/AuthorGambit.php index 4b08bb19c..89925efef 100644 --- a/framework/core/src/Core/Search/Discussions/Gambits/AuthorGambit.php +++ b/framework/core/src/Core/Search/Discussions/Gambits/AuthorGambit.php @@ -19,12 +19,12 @@ class AuthorGambit extends GambitAbstract $this->users = $users; } - public function conditions($matches, SearcherInterface $searcher) + protected function conditions(SearcherInterface $searcher, array $matches, $negate) { $username = trim($matches[1], '"'); $id = $this->users->getIdForUsername($username); - $searcher->query()->where('start_user_id', $id); + $searcher->getQuery()->where('start_user_id', $negate ? '!=' : '=', $id); } } diff --git a/framework/core/src/Core/Search/Discussions/Gambits/FulltextGambit.php b/framework/core/src/Core/Search/Discussions/Gambits/FulltextGambit.php index a476edde6..51e543b6a 100644 --- a/framework/core/src/Core/Search/Discussions/Gambits/FulltextGambit.php +++ b/framework/core/src/Core/Search/Discussions/Gambits/FulltextGambit.php @@ -2,9 +2,9 @@ use Flarum\Core\Repositories\PostRepositoryInterface; 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; @@ -24,7 +24,8 @@ class FulltextGambit extends GambitAbstract } $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]); } diff --git a/framework/core/src/Core/Search/Discussions/Gambits/UnreadGambit.php b/framework/core/src/Core/Search/Discussions/Gambits/UnreadGambit.php index 999bb5568..9c9f8428f 100644 --- a/framework/core/src/Core/Search/Discussions/Gambits/UnreadGambit.php +++ b/framework/core/src/Core/Search/Discussions/Gambits/UnreadGambit.php @@ -10,7 +10,7 @@ class UnreadGambit extends GambitAbstract * The gambit's regex pattern. * @var string */ - protected $pattern = 'unread:(true|false)'; + protected $pattern = 'is:unread'; protected $discussions; @@ -19,17 +19,17 @@ class UnreadGambit extends GambitAbstract $this->discussions = $discussions; } - protected function conditions($matches, SearcherInterface $searcher) + protected function conditions(SearcherInterface $searcher, array $matches, $negate) { $user = $searcher->user; if ($user->exists) { $readIds = $this->discussions->getReadIds($user); - if ($matches[1] === 'true') { - $searcher->query()->whereNotIn('id', $readIds)->where('last_time', '>', $user->read_time ?: 0); + if (! $negate) { + $searcher->getQuery()->whereNotIn('id', $readIds)->where('last_time', '>', $user->read_time ?: 0); } 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); } } } diff --git a/framework/core/src/Core/Search/GambitAbstract.php b/framework/core/src/Core/Search/GambitAbstract.php index ef1f64715..6220e90d3 100644 --- a/framework/core/src/Core/Search/GambitAbstract.php +++ b/framework/core/src/Core/Search/GambitAbstract.php @@ -7,15 +7,18 @@ abstract class GambitAbstract public function apply($bit, SearcherInterface $searcher) { if ($matches = $this->match($bit)) { - $this->conditions($matches, $searcher); + list($negate) = array_splice($matches, 1, 1); + $this->conditions($searcher, $matches, !! $negate); 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; } } + + abstract protected function conditions(SearcherInterface $searcher, array $matches, $negate); } diff --git a/framework/core/src/Core/Search/GambitInterface.php b/framework/core/src/Core/Search/GambitInterface.php index 0e6a5ab92..44bb536e7 100644 --- a/framework/core/src/Core/Search/GambitInterface.php +++ b/framework/core/src/Core/Search/GambitInterface.php @@ -2,5 +2,5 @@ interface GambitInterface { - public function apply($string, $searcher); + public function apply($string, SearcherInterface $searcher); } diff --git a/framework/core/src/Core/Search/SearcherInterface.php b/framework/core/src/Core/Search/SearcherInterface.php index 25945ecc7..f1e400ac4 100644 --- a/framework/core/src/Core/Search/SearcherInterface.php +++ b/framework/core/src/Core/Search/SearcherInterface.php @@ -2,7 +2,9 @@ interface SearcherInterface { - public function query(); + public function getQuery(); + + public function getUser(); public function setDefaultSort($defaultSort); } diff --git a/framework/core/src/Core/Search/Users/Gambits/FulltextGambit.php b/framework/core/src/Core/Search/Users/Gambits/FulltextGambit.php index db1043f36..4b2621315 100644 --- a/framework/core/src/Core/Search/Users/Gambits/FulltextGambit.php +++ b/framework/core/src/Core/Search/Users/Gambits/FulltextGambit.php @@ -2,9 +2,9 @@ use Flarum\Core\Repositories\UserRepositoryInterface; 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; @@ -17,7 +17,7 @@ class FulltextGambit extends GambitAbstract { $users = $this->users->getIdsForUsername($string, $searcher->user); - $searcher->query()->whereIn('id', $users); + $searcher->getQuery()->whereIn('id', $users); $searcher->setDefaultSort(['id' => $users]); } diff --git a/framework/core/src/Core/Search/Users/UserSearcher.php b/framework/core/src/Core/Search/Users/UserSearcher.php index 1106d2d56..da0dd2f7f 100644 --- a/framework/core/src/Core/Search/Users/UserSearcher.php +++ b/framework/core/src/Core/Search/Users/UserSearcher.php @@ -28,11 +28,16 @@ class UserSearcher implements SearcherInterface $this->defaultSort = $defaultSort; } - public function query() + public function getQuery() { return $this->query->getQuery(); } + public function getUser() + { + return $this->user; + } + public function addActiveGambit($gambit) { $this->activeGambits[] = $gambit;