commit before i lose this beauty

This commit is contained in:
Daniel Klabbers 2021-10-14 14:41:35 +02:00
parent f69541d38a
commit c9a0407f47
4 changed files with 84 additions and 39 deletions

View File

@ -22,7 +22,8 @@
"require": {
"php": ">= 8.0",
"flarum/core": "^1.0.0",
"elasticsearch/elasticsearch": "7.*"
"elasticsearch/elasticsearch": "7.*",
"spatie/elasticsearch-query-builder": "^1.3.0"
},
"extra": {
"flarum-extension": {

View File

@ -2,6 +2,7 @@
namespace Blomstra\Search\Api\Controllers;
use Blomstra\Search\Elasticsearch\TermsQuery;
use Blomstra\Search\Schemas\Schema;
use Elasticsearch\Client;
use Flarum\Api\Controller\AbstractListController;
@ -13,6 +14,10 @@ use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
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;
class SearchController extends AbstractListController
@ -30,23 +35,23 @@ class SearchController extends AbstractListController
$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();
$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();
return $schema::model()::query()->findMany($ids);
@ -69,7 +74,7 @@ class SearchController extends AbstractListController
return $manager->isEnabled($extension);
}
protected function getFilters(User $actor): string
protected function addFilters(BoolQuery $query, User $actor): BoolQuery
{
/** @var Collection $groups */
$groups = $actor->groups->pluck('id');
@ -78,22 +83,30 @@ class SearchController extends AbstractListController
if ($actor->is_email_confirmed) $groups->add(Group::MEMBER_ID);
$filters = sprintf(
'(%s)',
join(' OR ', $groups->map(function(int $id) {
return "groups = $id";
})->toArray())
);
$subQuery = BoolQuery::create()
->add(TermQuery::create('private', 'false'))
->add(TermsQuery::create('groups', $groups->toArray()));
if ($this->extensionEnabled('fof-byobu')) {
$filters .= sprintf(
" OR (private = true AND (recipient-users = $actor->id OR %s))",
join(' OR ', $groups->map(function(int $id) {
return "recipient-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'
);
$subQuery = BoolQuery::create()
->add($subQuery, 'should')
->add($byobuQuery, 'should');
}
return $filters;
$query->add(
$subQuery,
'filter'
);
return $query;
}
}

View File

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

View File

@ -18,7 +18,11 @@ class DiscussionSchema extends Schema
{
$filters = [];
$permissions = null;
$permissions = collect();
$globalPermission = Permission::query()
->where('permission', 'viewForum')
->pluck('group_id');
if ($this->extensionEnabled('flarum-tags')) {
/** @var \Illuminate\Database\Eloquent\Collection $tags */
@ -44,13 +48,8 @@ class DiscussionSchema extends Schema
})->flatten();
}
if (! $discussion->is_private && (! $permissions || $permissions->isEmpty())) {
$permissions = Permission::query()
->where('permission', 'viewForum')
->pluck('group_id');
} else {
$permissions = collect();
if (! $discussion->is_private && $permissions->isEmpty()) {
$permissions = $globalPermission;
}
$filters['groups'] = $permissions->toArray();