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;
}
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;
});
}

View File

@ -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);
}
}

View File

@ -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]);
}

View File

@ -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);
}
}
}

View File

@ -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);
}

View File

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

View File

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

View File

@ -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]);
}

View File

@ -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;