commit before i lose this beauty
This commit is contained in:
parent
f69541d38a
commit
c9a0407f47
|
|
@ -22,7 +22,8 @@
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">= 8.0",
|
"php": ">= 8.0",
|
||||||
"flarum/core": "^1.0.0",
|
"flarum/core": "^1.0.0",
|
||||||
"elasticsearch/elasticsearch": "7.*"
|
"elasticsearch/elasticsearch": "7.*",
|
||||||
|
"spatie/elasticsearch-query-builder": "^1.3.0"
|
||||||
},
|
},
|
||||||
"extra": {
|
"extra": {
|
||||||
"flarum-extension": {
|
"flarum-extension": {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Blomstra\Search\Api\Controllers;
|
namespace Blomstra\Search\Api\Controllers;
|
||||||
|
|
||||||
|
use Blomstra\Search\Elasticsearch\TermsQuery;
|
||||||
use Blomstra\Search\Schemas\Schema;
|
use Blomstra\Search\Schemas\Schema;
|
||||||
use Elasticsearch\Client;
|
use Elasticsearch\Client;
|
||||||
use Flarum\Api\Controller\AbstractListController;
|
use Flarum\Api\Controller\AbstractListController;
|
||||||
|
|
@ -13,6 +14,10 @@ use Illuminate\Contracts\Container\Container;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Spatie\ElasticsearchQueryBuilder\Builder;
|
||||||
|
use Spatie\ElasticsearchQueryBuilder\Queries\BoolQuery;
|
||||||
|
use Spatie\ElasticsearchQueryBuilder\Queries\MultiMatchQuery;
|
||||||
|
use Spatie\ElasticsearchQueryBuilder\Queries\TermQuery;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
class SearchController extends AbstractListController
|
class SearchController extends AbstractListController
|
||||||
|
|
@ -30,23 +35,23 @@ class SearchController extends AbstractListController
|
||||||
|
|
||||||
$schema = $this->getSchema($index);
|
$schema = $this->getSchema($index);
|
||||||
|
|
||||||
$result = $client->search([
|
|
||||||
'index' => $index,
|
|
||||||
'from' => $this->extractOffset($request),
|
|
||||||
'size' => $this->extractLimit($request),
|
|
||||||
'sort' => $this->extractSort($request),
|
|
||||||
'body' => [
|
|
||||||
'query' => [
|
|
||||||
'multi_match' => [
|
|
||||||
'query' => $filters['q'],
|
|
||||||
'fields' => array_keys($schema->fulltext(new ($schema::model())))
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->serializer = $schema::serializer();
|
$this->serializer = $schema::serializer();
|
||||||
|
|
||||||
|
$filterQuery = (BoolQuery::create())
|
||||||
|
->add(
|
||||||
|
MultiMatchQuery::create($filters['q'], array_keys($schema->fulltext(new ($schema::model())))),
|
||||||
|
'must'
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = (new Builder($client))
|
||||||
|
->index($index)
|
||||||
|
->size($this->extractLimit($request))
|
||||||
|
->from($this->extractOffset($request))
|
||||||
|
->addQuery(
|
||||||
|
$this->addFilters($filterQuery, $actor)
|
||||||
|
)
|
||||||
|
->search();
|
||||||
|
|
||||||
$ids = Collection::make(Arr::get($result, 'hits.hits'))->pluck('_id')->toArray();
|
$ids = Collection::make(Arr::get($result, 'hits.hits'))->pluck('_id')->toArray();
|
||||||
|
|
||||||
return $schema::model()::query()->findMany($ids);
|
return $schema::model()::query()->findMany($ids);
|
||||||
|
|
@ -69,7 +74,7 @@ class SearchController extends AbstractListController
|
||||||
return $manager->isEnabled($extension);
|
return $manager->isEnabled($extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getFilters(User $actor): string
|
protected function addFilters(BoolQuery $query, User $actor): BoolQuery
|
||||||
{
|
{
|
||||||
/** @var Collection $groups */
|
/** @var Collection $groups */
|
||||||
$groups = $actor->groups->pluck('id');
|
$groups = $actor->groups->pluck('id');
|
||||||
|
|
@ -78,22 +83,30 @@ class SearchController extends AbstractListController
|
||||||
|
|
||||||
if ($actor->is_email_confirmed) $groups->add(Group::MEMBER_ID);
|
if ($actor->is_email_confirmed) $groups->add(Group::MEMBER_ID);
|
||||||
|
|
||||||
$filters = sprintf(
|
$subQuery = BoolQuery::create()
|
||||||
'(%s)',
|
->add(TermQuery::create('private', 'false'))
|
||||||
join(' OR ', $groups->map(function(int $id) {
|
->add(TermsQuery::create('groups', $groups->toArray()));
|
||||||
return "groups = $id";
|
|
||||||
})->toArray())
|
if ($this->extensionEnabled('fof-byobu') && $actor->exists) {
|
||||||
|
$byobuQuery = BoolQuery::create()
|
||||||
|
->add(TermQuery::create('private', 'true'), 'should')
|
||||||
|
->add(
|
||||||
|
BoolQuery::create()
|
||||||
|
->add(TermsQuery::create('recipient-groups', $groups->toArray()))
|
||||||
|
->add(TermQuery::create('recipient-users', $actor->id)),
|
||||||
|
'should'
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($this->extensionEnabled('fof-byobu')) {
|
$subQuery = BoolQuery::create()
|
||||||
$filters .= sprintf(
|
->add($subQuery, 'should')
|
||||||
" OR (private = true AND (recipient-users = $actor->id OR %s))",
|
->add($byobuQuery, 'should');
|
||||||
join(' OR ', $groups->map(function(int $id) {
|
|
||||||
return "recipient-groups = $id";
|
|
||||||
})->toArray())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $filters;
|
$query->add(
|
||||||
|
$subQuery,
|
||||||
|
'filter'
|
||||||
|
);
|
||||||
|
|
||||||
|
return $query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Blomstra\Search\Elasticsearch;
|
||||||
|
|
||||||
|
use Spatie\ElasticsearchQueryBuilder\Queries\Query;
|
||||||
|
|
||||||
|
class TermsQuery implements Query
|
||||||
|
{
|
||||||
|
protected string $field;
|
||||||
|
|
||||||
|
protected array $value;
|
||||||
|
|
||||||
|
public static function create(string $field, array $value): static
|
||||||
|
{
|
||||||
|
return new self($field, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct(string $field, array $value)
|
||||||
|
{
|
||||||
|
$this->field = $field;
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toArray(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'terms' => [
|
||||||
|
$this->field => $this->value,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,7 +18,11 @@ class DiscussionSchema extends Schema
|
||||||
{
|
{
|
||||||
$filters = [];
|
$filters = [];
|
||||||
|
|
||||||
$permissions = null;
|
$permissions = collect();
|
||||||
|
|
||||||
|
$globalPermission = Permission::query()
|
||||||
|
->where('permission', 'viewForum')
|
||||||
|
->pluck('group_id');
|
||||||
|
|
||||||
if ($this->extensionEnabled('flarum-tags')) {
|
if ($this->extensionEnabled('flarum-tags')) {
|
||||||
/** @var \Illuminate\Database\Eloquent\Collection $tags */
|
/** @var \Illuminate\Database\Eloquent\Collection $tags */
|
||||||
|
|
@ -44,13 +48,8 @@ class DiscussionSchema extends Schema
|
||||||
})->flatten();
|
})->flatten();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! $discussion->is_private && (! $permissions || $permissions->isEmpty())) {
|
if (! $discussion->is_private && $permissions->isEmpty()) {
|
||||||
$permissions = Permission::query()
|
$permissions = $globalPermission;
|
||||||
->where('permission', 'viewForum')
|
|
||||||
->pluck('group_id');
|
|
||||||
|
|
||||||
} else {
|
|
||||||
$permissions = collect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$filters['groups'] = $permissions->toArray();
|
$filters['groups'] = $permissions->toArray();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue