1
0
mirror of https://github.com/flarum/core.git synced 2025-08-05 16:07:34 +02:00

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 array $where
* @param \Flarum\Core\Models\User|null $user * @param \Flarum\Core\Models\User|null $user
* @param string $sort * @param array $sort
* @param string $order
* @param integer $count * @param integer $count
* @param integer $start * @param integer $start
* @return \Illuminate\Database\Eloquent\Collection * @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) $query = Post::where($where)
->orderBy($sort, $order)
->skip($start) ->skip($start)
->take($count); ->take($count);
foreach ((array) $sort as $field => $order) {
$query->orderBy($field, $order);
}
return $this->scopeVisibleForUser($query, $user)->get(); return $this->scopeVisibleForUser($query, $user)->get();
} }

View File

@@ -22,13 +22,12 @@ interface PostRepositoryInterface
* *
* @param array $where * @param array $where
* @param \Flarum\Core\Models\User|null $user * @param \Flarum\Core\Models\User|null $user
* @param string $sort * @param array $sort
* @param string $order
* @param integer $count * @param integer $count
* @param integer $start * @param integer $start
* @return \Illuminate\Database\Eloquent\Collection * @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 * Find posts by their IDs, optionally making sure they are visible to a

View File

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

View File

@@ -11,20 +11,14 @@ class DiscussionSearcher implements SearcherInterface
{ {
public $query; public $query;
protected $sortMap = [
'lastPost' => ['last_time', 'desc'],
'replies' => ['comments_count', 'desc'],
'created' => ['start_time', 'asc']
];
protected $defaultSort = 'lastPost';
protected $relevantPosts = []; protected $relevantPosts = [];
protected $gambits; protected $gambits;
protected $discussions; protected $discussions;
protected $defaultSort = ['lastTime' => 'desc'];
public function __construct(GambitManager $gambits, DiscussionRepositoryInterface $discussions, PostRepositoryInterface $posts) public function __construct(GambitManager $gambits, DiscussionRepositoryInterface $discussions, PostRepositoryInterface $posts)
{ {
$this->gambits = $gambits; $this->gambits = $gambits;
@@ -50,7 +44,7 @@ class DiscussionSearcher implements SearcherInterface
return $this->query->getQuery(); 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->user = $criteria->user;
$this->query = $this->discussions->query()->whereCan($criteria->user, 'view'); $this->query = $this->discussions->query()->whereCan($criteria->user, 'view');
@@ -59,31 +53,30 @@ class DiscussionSearcher implements SearcherInterface
$total = $this->query->count(); $total = $this->query->count();
if (empty($criteria->sort)) { $sort = $criteria->sort ?: $this->defaultSort;
$criteria->sort = $this->defaultSort;
} foreach ($sort as $field => $order) {
$sort = $criteria->sort; if (is_array($order)) {
if (is_array($sort)) { foreach ($order as $value) {
foreach ($sort as $id) { $this->query->orderByRaw(snake_case($field).' != ?', [$value]);
$this->query->orderByRaw('id != '.(int) $id); }
} 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) { if ($offset > 0) {
$this->query->skip($start); $this->query->skip($offset);
} }
if ($count > 0) { if ($limit > 0) {
$this->query->take($count + 1); $this->query->take($limit + 1);
} }
event(new SearchWillBePerformed($this, $criteria)); event(new SearchWillBePerformed($this, $criteria));
$discussions = $this->query->get(); $discussions = $this->query->get();
if ($count > 0 && $areMoreResults = $discussions->count() > $count) { if ($limit > 0 && $areMoreResults = $discussions->count() > $limit) {
$discussions->pop(); $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); Discussion::setStateUser($this->user);
$discussions->load($load); $discussions->load($load);

View File

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