Update discussion/post sort semantics inline with new API actions

Instead of $sort and $order being separate, they are now a single
array, allowing multiple sort criteria: `[‘foo’ => ‘asc', ‘bar’ =>
‘desc’]`
This commit is contained in:
Toby Zerner 2015-05-02 09:00:07 +09:30
parent 22ff8a203d
commit 8ee9480205
5 changed files with 28 additions and 36 deletions

View File

@ -29,19 +29,21 @@ class EloquentPostRepository implements PostRepositoryInterface
*
* @param array $where
* @param \Flarum\Core\Models\User|null $user
* @param string $sort
* @param string $order
* @param array $sort
* @param integer $count
* @param integer $start
* @return \Illuminate\Database\Eloquent\Collection
*/
public function findWhere($where = [], User $user = null, $sort = 'time', $order = 'asc', $count = null, $start = 0)
public function findWhere($where = [], User $user = null, $sort = [], $count = null, $start = 0)
{
$query = Post::where($where)
->orderBy($sort, $order)
->skip($start)
->take($count);
foreach ((array) $sort as $field => $order) {
$query->orderBy($field, $order);
}
return $this->scopeVisibleForUser($query, $user)->get();
}

View File

@ -22,13 +22,12 @@ interface PostRepositoryInterface
*
* @param array $where
* @param \Flarum\Core\Models\User|null $user
* @param string $sort
* @param string $order
* @param array $sort
* @param integer $count
* @param integer $start
* @return \Illuminate\Database\Eloquent\Collection
*/
public function findWhere($where = [], User $user = null, $sort = 'time', $order = 'asc', $count = null, $start = 0);
public function findWhere($where = [], User $user = null, $sort = [], $count = null, $start = 0);
/**
* Find posts by their IDs, optionally making sure they are visible to a

View File

@ -8,13 +8,10 @@ class DiscussionSearchCriteria
public $sort;
public $order;
public function __construct($user, $query, $sort, $order)
public function __construct($user, $query, $sort)
{
$this->user = $user;
$this->query = $query;
$this->sort = $sort;
$this->order = $order;
}
}

View File

@ -11,20 +11,14 @@ class DiscussionSearcher implements SearcherInterface
{
public $query;
protected $sortMap = [
'lastPost' => ['last_time', 'desc'],
'replies' => ['comments_count', 'desc'],
'created' => ['start_time', 'asc']
];
protected $defaultSort = 'lastPost';
protected $relevantPosts = [];
protected $gambits;
protected $discussions;
protected $defaultSort = ['lastTime' => 'desc'];
public function __construct(GambitManager $gambits, DiscussionRepositoryInterface $discussions, PostRepositoryInterface $posts)
{
$this->gambits = $gambits;
@ -50,7 +44,7 @@ class DiscussionSearcher implements SearcherInterface
return $this->query->getQuery();
}
public function search(DiscussionSearchCriteria $criteria, $count = null, $start = 0, $load = [])
public function search(DiscussionSearchCriteria $criteria, $limit = null, $offset = 0, $load = [])
{
$this->user = $criteria->user;
$this->query = $this->discussions->query()->whereCan($criteria->user, 'view');
@ -59,31 +53,30 @@ class DiscussionSearcher implements SearcherInterface
$total = $this->query->count();
if (empty($criteria->sort)) {
$criteria->sort = $this->defaultSort;
}
$sort = $criteria->sort;
if (is_array($sort)) {
foreach ($sort as $id) {
$this->query->orderByRaw('id != '.(int) $id);
$sort = $criteria->sort ?: $this->defaultSort;
foreach ($sort as $field => $order) {
if (is_array($order)) {
foreach ($order as $value) {
$this->query->orderByRaw(snake_case($field).' != ?', [$value]);
}
} else {
$this->query->orderBy(snake_case($field), $order);
}
} else {
list($column, $order) = $this->sortMap[$sort];
$this->query->orderBy($column, $criteria->order ?: $order);
}
if ($start > 0) {
$this->query->skip($start);
if ($offset > 0) {
$this->query->skip($offset);
}
if ($count > 0) {
$this->query->take($count + 1);
if ($limit > 0) {
$this->query->take($limit + 1);
}
event(new SearchWillBePerformed($this, $criteria));
$discussions = $this->query->get();
if ($count > 0 && $areMoreResults = $discussions->count() > $count) {
if ($limit > 0 && $areMoreResults = $discussions->count() > $limit) {
$discussions->pop();
}
@ -109,6 +102,7 @@ class DiscussionSearcher implements SearcherInterface
}
}
// @todo make instance rather than static and set on all discussions
Discussion::setStateUser($this->user);
$discussions->load($load);

View File

@ -26,6 +26,6 @@ class FulltextGambit extends GambitAbstract
$searcher->query()->whereIn('id', $discussions);
$searcher->setDefaultSort($discussions);
$searcher->setDefaultSort(['id' => $discussions]);
}
}