1
0
mirror of https://github.com/flarum/core.git synced 2025-10-20 19:27:14 +02:00
Files
php-flarum/src/Core/Search/Discussions/DiscussionSearcher.php
Toby Zerner 2c46888db5 Upgrade to L5 + huge refactor + more. closes #2
New stuff:
- Signup + email confirmation.
- Updated authentication strategy with remember cookies. closes #5
- New search system with some example gambits! This is cool - check out
the source. Fulltext drivers will be implemented as decorators
overriding the EloquentPostRepository’s findByContent method.
- Lay down the foundation for bootstrapping the Ember app.
- Update Web layer’s asset manager to properly publish CSS/JS files.
- Console commands to run installation migrations and seeds.

Refactoring:
- New structure: move models, repositories, commands, and events into
their own namespaces, rather than grouping by entity.
- All events are classes.
- Use L5 middleware and command bus implementations.
- Clearer use of repositories and the Active Record pattern.
Repositories are used only for retrieval of ActiveRecord objects, and
then save/delete operations are called directly on those ActiveRecords.
This way, we don’t over-abstract at the cost of Eloquent magic, but
testing is still easy.
- Refactor of Web layer so that it uses the Actions routing
architecture.
- “Actor” concept instead of depending on Laravel’s Auth.
- General cleanup!
2015-02-24 20:33:18 +10:30

110 lines
3.4 KiB
PHP

<?php namespace Flarum\Core\Search\Discussions;
use Flarum\Core\Models\Discussion;
use Flarum\Core\Search\GambitManager;
use Flarum\Core\Repositories\DiscussionRepositoryInterface;
use Flarum\Core\Repositories\PostRepositoryInterface;
class DiscussionSearcher
{
public $query;
protected $sortMap = [
'lastPost' => ['last_time', 'desc'],
'replies' => ['comments_count', 'desc'],
'created' => ['start_time', 'desc']
];
protected $defaultSort = 'lastPost';
protected $relevantPosts = [];
protected $gambits;
protected $discussions;
public function __construct(GambitManager $gambits, DiscussionRepositoryInterface $discussions, PostRepositoryInterface $posts)
{
$this->gambits = $gambits;
$this->discussions = $discussions;
$this->posts = $posts;
}
public function addRelevantPost($discussionId, $postId)
{
if (empty($this->relevantPosts[$discussionId])) {
$this->relevantPosts[$discussionId] = [];
}
$this->relevantPosts[$discussionId][] = $postId;
}
public function setDefaultSort($defaultSort)
{
$this->defaultSort = $defaultSort;
}
public function search(DiscussionSearchCriteria $criteria, $count = null, $start = 0, $load = [])
{
$this->user = $criteria->user;
$this->query = $this->discussions->query()->whereCan($criteria->user, 'view');
$this->gambits->apply($criteria->query, $this);
$total = $this->query->count();
$sort = $criteria->sort;
if (empty($sort)) {
$sort = $this->defaultSort;
}
// dd($sort);
if (is_array($sort)) {
foreach ($sort as $id) {
$this->query->orderByRaw('id != '.(int) $id);
}
} else {
list($column, $order) = $this->sortMap[$sort];
$this->query->orderBy($column, $criteria->order ?: $order);
}
if ($start > 0) {
$this->query->skip($start);
}
if ($count > 0) {
$this->query->take($count + 1);
}
$discussions = $this->query->get();
if ($count > 0 && $areMoreResults = $discussions->count() > $count) {
$discussions->pop();
}
if (in_array('relevantPosts', $load) && count($this->relevantPosts)) {
$load = array_diff($load, ['relevantPosts']);
$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');
foreach ($discussions as $discussion) {
$discussion->relevantPosts = $posts->filter(function ($post) use ($discussion) {
return $post->discussion_id == $discussion->id;
})
->each(function ($post) {
$pos = strpos(strtolower($post->content), strtolower($this->fulltext));
// TODO: make clipping more intelligent (full words only)
$start = max(0, $pos - 50);
$post->content = ($start > 0 ? '...' : '').str_limit(substr($post->content, $start), 300);
});
}
}
Discussion::setStateUser($this->user);
$discussions->load($load);
return new DiscussionSearchResults($discussions, $areMoreResults, $total);
}
}