Apply fixes from StyleCI
This commit is contained in:
parent
4240269b7f
commit
f8aa3dcf13
22
extend.php
22
extend.php
|
|
@ -1,23 +1,33 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search;
|
namespace Blomstra\Search;
|
||||||
|
|
||||||
use Flarum\Extend as Flarum;
|
use Flarum\Extend as Flarum;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
(new Flarum\ServiceProvider)->register(Provider::class),
|
(new Flarum\ServiceProvider())->register(Provider::class),
|
||||||
|
|
||||||
(new Flarum\Frontend('forum'))
|
(new Flarum\Frontend('forum'))
|
||||||
->js(__DIR__ . '/js/dist/forum.js'),
|
->js(__DIR__.'/js/dist/forum.js'),
|
||||||
(new Flarum\Frontend('admin'))
|
(new Flarum\Frontend('admin'))
|
||||||
->js(__DIR__ . '/js/dist/admin.js'),
|
->js(__DIR__.'/js/dist/admin.js'),
|
||||||
|
|
||||||
(new Flarum\Locales(__DIR__ . '/resources/locale')),
|
(new Flarum\Locales(__DIR__.'/resources/locale')),
|
||||||
|
|
||||||
(new Flarum\Routes('api'))
|
(new Flarum\Routes('api'))
|
||||||
->get('/blomstra/search/{type}', 'blomstra.search', Api\Controllers\SearchController::class)
|
->get('/blomstra/search/{type}', 'blomstra.search', Api\Controllers\SearchController::class)
|
||||||
->put('/blomstra/search/index', 'blomstra.search.index', Api\Controllers\IndexController::class),
|
->put('/blomstra/search/index', 'blomstra.search.index', Api\Controllers\IndexController::class),
|
||||||
|
|
||||||
(new Flarum\Console)
|
(new Flarum\Console())
|
||||||
->command(Commands\BuildCommand::class)
|
->command(Commands\BuildCommand::class),
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Api;
|
namespace Blomstra\Search\Api;
|
||||||
|
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
|
|
@ -9,7 +19,9 @@ class Client extends \Flarum\Api\Client
|
||||||
{
|
{
|
||||||
public function get(string $path): ResponseInterface
|
public function get(string $path): ResponseInterface
|
||||||
{
|
{
|
||||||
if ($path === '/discussions' && Arr::has($this->queryParams, 'filter.q')) return parent::get("/blomstra/search/discussions");
|
if ($path === '/discussions' && Arr::has($this->queryParams, 'filter.q')) {
|
||||||
|
return parent::get('/blomstra/search/discussions');
|
||||||
|
}
|
||||||
|
|
||||||
return parent::get($path);
|
return parent::get($path);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Api\Controllers;
|
namespace Blomstra\Search\Api\Controllers;
|
||||||
|
|
||||||
use Blomstra\Search\Commands\BuildCommand;
|
use Blomstra\Search\Commands\BuildCommand;
|
||||||
|
|
@ -23,7 +33,8 @@ class IndexController implements RequestHandlerInterface
|
||||||
|
|
||||||
$command->run(
|
$command->run(
|
||||||
new ArrayInput([]),
|
new ArrayInput([]),
|
||||||
new ConsoleOutput);
|
new ConsoleOutput()
|
||||||
|
);
|
||||||
|
|
||||||
return new EmptyResponse();
|
return new EmptyResponse();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,21 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Api\Controllers;
|
namespace Blomstra\Search\Api\Controllers;
|
||||||
|
|
||||||
use Blomstra\Search\Elasticsearch\MatchPhraseQuery;
|
use Blomstra\Search\Elasticsearch\MatchPhraseQuery;
|
||||||
use Blomstra\Search\Elasticsearch\MatchQuery;
|
use Blomstra\Search\Elasticsearch\MatchQuery;
|
||||||
use Blomstra\Search\Save\Document as ElasticDocument;
|
|
||||||
use Blomstra\Search\Elasticsearch\TermsQuery;
|
use Blomstra\Search\Elasticsearch\TermsQuery;
|
||||||
|
use Blomstra\Search\Save\Document as ElasticDocument;
|
||||||
use Elasticsearch\Client;
|
use Elasticsearch\Client;
|
||||||
use Flarum\Api\Controller\ListDiscussionsController;
|
use Flarum\Api\Controller\ListDiscussionsController;
|
||||||
use Flarum\Api\Serializer\DiscussionSerializer;
|
use Flarum\Api\Serializer\DiscussionSerializer;
|
||||||
|
|
@ -33,12 +43,13 @@ class SearchController extends ListDiscussionsController
|
||||||
|
|
||||||
protected array $translateSort = [
|
protected array $translateSort = [
|
||||||
'lastPostedAt' => 'updated_at',
|
'lastPostedAt' => 'updated_at',
|
||||||
'createdAt' => 'created_at',
|
'createdAt' => 'created_at',
|
||||||
'commentCount' => 'comment_count'
|
'commentCount' => 'comment_count',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct(protected Client $elastic, protected UrlGenerator $uri)
|
public function __construct(protected Client $elastic, protected UrlGenerator $uri)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
protected function data(ServerRequestInterface $request, Document $document)
|
protected function data(ServerRequestInterface $request, Document $document)
|
||||||
{
|
{
|
||||||
|
|
@ -58,14 +69,14 @@ class SearchController extends ListDiscussionsController
|
||||||
|
|
||||||
$filterQuery = BoolQuery::create();
|
$filterQuery = BoolQuery::create();
|
||||||
|
|
||||||
if (! empty($search)) {
|
if (!empty($search)) {
|
||||||
$filterQuery
|
$filterQuery
|
||||||
// @todo commented out to use only partial matching for now
|
// @todo commented out to use only partial matching for now
|
||||||
->add($this->sentenceMatch($search))
|
->add($this->sentenceMatch($search))
|
||||||
->add($this->wordMatch($search, 'and'))
|
->add($this->wordMatch($search, 'and'))
|
||||||
->add($this->wordMatch($search, 'or'))
|
->add($this->wordMatch($search, 'or'))
|
||||||
// ->add($this->partialMatch($search))
|
// ->add($this->partialMatch($search))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
$builder = (new Builder($this->elastic))
|
$builder = (new Builder($this->elastic))
|
||||||
|
|
@ -91,7 +102,7 @@ class SearchController extends ListDiscussionsController
|
||||||
|
|
||||||
// If the first level of the relationship wasn't explicitly included,
|
// If the first level of the relationship wasn't explicitly included,
|
||||||
// add it so the code below can look for it
|
// add it so the code below can look for it
|
||||||
if (! in_array('mostRelevantPost', $include)) {
|
if (!in_array('mostRelevantPost', $include)) {
|
||||||
$include[] = 'mostRelevantPost';
|
$include[] = 'mostRelevantPost';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -106,19 +117,19 @@ class SearchController extends ListDiscussionsController
|
||||||
if ($type === 'posts') {
|
if ($type === 'posts') {
|
||||||
return [
|
return [
|
||||||
'most_relevant_post_id' => $id,
|
'most_relevant_post_id' => $id,
|
||||||
'weight' => Arr::get($hit, 'sort.0')
|
'weight' => Arr::get($hit, 'sort.0'),
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
return [
|
return [
|
||||||
'discussion_id' => $id,
|
'discussion_id' => $id,
|
||||||
'weight' => Arr::get($hit, 'sort.0')
|
'weight' => Arr::get($hit, 'sort.0'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$document->addPaginationLinks(
|
$document->addPaginationLinks(
|
||||||
$this->uri->to('api')->route('blomstra.search', [
|
$this->uri->to('api')->route('blomstra.search', [
|
||||||
'type' => 'discussions'
|
'type' => 'discussions',
|
||||||
]),
|
]),
|
||||||
$request->getQueryParams(),
|
$request->getQueryParams(),
|
||||||
$offset,
|
$offset,
|
||||||
|
|
@ -132,7 +143,7 @@ class SearchController extends ListDiscussionsController
|
||||||
->select('discussions.*')
|
->select('discussions.*')
|
||||||
->join('posts', 'posts.discussion_id', 'discussions.id')
|
->join('posts', 'posts.discussion_id', 'discussions.id')
|
||||||
// Extra safety to prevent leaking hidden discussion (titles) towards search results.
|
// Extra safety to prevent leaking hidden discussion (titles) towards search results.
|
||||||
->when($actor->isGuest() || ! $actor->hasPermission('discussion.hide'), fn($query) => $query->whereNull('discussions.hidden_at'))
|
->when($actor->isGuest() || !$actor->hasPermission('discussion.hide'), fn ($query) => $query->whereNull('discussions.hidden_at'))
|
||||||
->where(function ($query) use ($results) {
|
->where(function ($query) use ($results) {
|
||||||
$query
|
$query
|
||||||
->whereIn('discussions.id', $results->pluck('discussion_id')->filter())
|
->whereIn('discussions.id', $results->pluck('discussion_id')->filter())
|
||||||
|
|
@ -287,7 +298,6 @@ class SearchController extends ListDiscussionsController
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected function getGroups(User $actor): Collection
|
protected function getGroups(User $actor): Collection
|
||||||
{
|
{
|
||||||
/** @var Collection $groups */
|
/** @var Collection $groups */
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,20 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Commands;
|
namespace Blomstra\Search\Commands;
|
||||||
|
|
||||||
use Blomstra\Search\Jobs\Job;
|
use Blomstra\Search\Jobs\Job;
|
||||||
use Blomstra\Search\Jobs\SavingJob;
|
use Blomstra\Search\Jobs\SavingJob;
|
||||||
use Blomstra\Search\Seeders\Seeder;
|
use Blomstra\Search\Seeders\Seeder;
|
||||||
use Carbon\Carbon;
|
|
||||||
use Elasticsearch\Client;
|
use Elasticsearch\Client;
|
||||||
use Flarum\Settings\SettingsRepositoryInterface;
|
use Flarum\Settings\SettingsRepositoryInterface;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
@ -43,23 +52,23 @@ class BuildCommand extends Command
|
||||||
|
|
||||||
$properties = [
|
$properties = [
|
||||||
'properties' => [
|
'properties' => [
|
||||||
'content' => ['type' => 'text', 'analyzer' => 'flarum_analyzer_partial', 'search_analyzer' => 'flarum_analyzer'],
|
'content' => ['type' => 'text', 'analyzer' => 'flarum_analyzer_partial', 'search_analyzer' => 'flarum_analyzer'],
|
||||||
'created_at' => ['type' => 'date'],
|
'created_at' => ['type' => 'date'],
|
||||||
'updated_at' => ['type' => 'date'],
|
'updated_at' => ['type' => 'date'],
|
||||||
'is_private' => ['type' => 'boolean'],
|
'is_private' => ['type' => 'boolean'],
|
||||||
'is_sticky' => ['type' => 'boolean'],
|
'is_sticky' => ['type' => 'boolean'],
|
||||||
'groups' => ['type' => 'integer'],
|
'groups' => ['type' => 'integer'],
|
||||||
'recipient_groups' => ['type' => 'integer'],
|
'recipient_groups' => ['type' => 'integer'],
|
||||||
'recipient_users' => ['type' => 'integer'],
|
'recipient_users' => ['type' => 'integer'],
|
||||||
'comment_count' => ['type' => 'integer'],
|
'comment_count' => ['type' => 'integer'],
|
||||||
]
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($this->option('recreate')) {
|
if ($this->option('recreate')) {
|
||||||
// Flush the index.
|
// Flush the index.
|
||||||
$client->indices()->delete([
|
$client->indices()->delete([
|
||||||
'index' => $index,
|
'index' => $index,
|
||||||
'ignore_unavailable' => true
|
'ignore_unavailable' => true,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Create a new index.
|
// Create a new index.
|
||||||
|
|
@ -68,38 +77,38 @@ class BuildCommand extends Command
|
||||||
'body' => [
|
'body' => [
|
||||||
'settings' => [
|
'settings' => [
|
||||||
'index.max_ngram_diff' => 10,
|
'index.max_ngram_diff' => 10,
|
||||||
'analysis' => [
|
'analysis' => [
|
||||||
'analyzer' => [
|
'analyzer' => [
|
||||||
'flarum_analyzer' => [
|
'flarum_analyzer' => [
|
||||||
'type' => $settings->get('blomstra-search.analyzer-language') ?: 'english'
|
'type' => $settings->get('blomstra-search.analyzer-language') ?: 'english',
|
||||||
],
|
],
|
||||||
'flarum_analyzer_partial' => [
|
'flarum_analyzer_partial' => [
|
||||||
'type' => 'custom',
|
'type' => 'custom',
|
||||||
'tokenizer' => 'standard',
|
'tokenizer' => 'standard',
|
||||||
'filter' => [
|
'filter' => [
|
||||||
'lowercase',
|
'lowercase',
|
||||||
'partial_search_filter'
|
'partial_search_filter',
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
],
|
],
|
||||||
'filter' => [
|
'filter' => [
|
||||||
'partial_search_filter' => [
|
'partial_search_filter' => [
|
||||||
'type' => 'ngram',
|
'type' => 'ngram',
|
||||||
'min_gram' => 1,
|
'min_gram' => 1,
|
||||||
'max_gram' => 10,
|
'max_gram' => 10,
|
||||||
'token_chars' => ['letter', 'digit', 'symbol']
|
'token_chars' => ['letter', 'digit', 'symbol'],
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->option('recreate') || $this->option('mapping')) {
|
if ($this->option('recreate') || $this->option('mapping')) {
|
||||||
$client->indices()->putMapping([
|
$client->indices()->putMapping([
|
||||||
'index' => $index,
|
'index' => $index,
|
||||||
'body' => $properties
|
'body' => $properties,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,7 +116,9 @@ class BuildCommand extends Command
|
||||||
|
|
||||||
/** @var Seeder $seeder */
|
/** @var Seeder $seeder */
|
||||||
foreach ($seeders as $seeder) {
|
foreach ($seeders as $seeder) {
|
||||||
if ($only && $seeder->type() !== $only) continue;
|
if ($only && $seeder->type() !== $only) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$total = 0;
|
$total = 0;
|
||||||
|
|
||||||
|
|
@ -115,7 +126,7 @@ class BuildCommand extends Command
|
||||||
? ($this->continueAt($seeder->type()) ?? $seeder->query()->max('id'))
|
? ($this->continueAt($seeder->type()) ?? $seeder->query()->max('id'))
|
||||||
: $seeder->query()->max('id');
|
: $seeder->query()->max('id');
|
||||||
|
|
||||||
while($continueAt !== null) {
|
while ($continueAt !== null) {
|
||||||
/** @var Collection $collection */
|
/** @var Collection $collection */
|
||||||
$collection = $seeder->query()
|
$collection = $seeder->query()
|
||||||
->latest('id')
|
->latest('id')
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Elasticsearch;
|
namespace Blomstra\Search\Elasticsearch;
|
||||||
|
|
||||||
use Spatie\ElasticsearchQueryBuilder\Queries\MatchQuery;
|
use Spatie\ElasticsearchQueryBuilder\Queries\MatchQuery;
|
||||||
|
|
@ -22,7 +32,7 @@ class MatchPhraseQuery extends MatchQuery
|
||||||
$query[$this->field]['boost'] = $this->boost;
|
$query[$this->field]['boost'] = $this->boost;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'match_phrase' => $query
|
'match_phrase' => $query,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Elasticsearch;
|
namespace Blomstra\Search\Elasticsearch;
|
||||||
|
|
||||||
class MatchQuery extends \Spatie\ElasticsearchQueryBuilder\Queries\MatchQuery
|
class MatchQuery extends \Spatie\ElasticsearchQueryBuilder\Queries\MatchQuery
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Elasticsearch;
|
namespace Blomstra\Search\Elasticsearch;
|
||||||
|
|
||||||
use Spatie\ElasticsearchQueryBuilder\Queries\Query;
|
use Spatie\ElasticsearchQueryBuilder\Queries\Query;
|
||||||
|
|
@ -38,12 +48,12 @@ class SimpleSearchQuery implements Query
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'simple_query_string' => [
|
'simple_query_string' => [
|
||||||
'query' => $this->value,
|
'query' => $this->value,
|
||||||
'fields' => $this->fields,
|
'fields' => $this->fields,
|
||||||
'analyzer' => $this->analyzer,
|
'analyzer' => $this->analyzer,
|
||||||
'default_operator' => 'AND',
|
'default_operator' => 'AND',
|
||||||
'boost' => $this->boost
|
'boost' => $this->boost,
|
||||||
]
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Elasticsearch;
|
namespace Blomstra\Search\Elasticsearch;
|
||||||
|
|
||||||
use Spatie\ElasticsearchQueryBuilder\Queries\Query;
|
use Spatie\ElasticsearchQueryBuilder\Queries\Query;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Elasticsearch;
|
namespace Blomstra\Search\Elasticsearch;
|
||||||
|
|
||||||
class WildcardQuery extends \Spatie\ElasticsearchQueryBuilder\Queries\WildcardQuery
|
class WildcardQuery extends \Spatie\ElasticsearchQueryBuilder\Queries\WildcardQuery
|
||||||
|
|
@ -34,11 +44,10 @@ class WildcardQuery extends \Spatie\ElasticsearchQueryBuilder\Queries\WildcardQu
|
||||||
$query = parent::toArray();
|
$query = parent::toArray();
|
||||||
|
|
||||||
$query['wildcard'][$this->field]['boost'] = $this->boost;
|
$query['wildcard'][$this->field]['boost'] = $this->boost;
|
||||||
$query['wildcard'][$this->field]['case_insensitive'] = ! $this->sensitivity;
|
$query['wildcard'][$this->field]['case_insensitive'] = !$this->sensitivity;
|
||||||
|
|
||||||
if ($this->rewrite) {
|
if ($this->rewrite) {
|
||||||
$query['wildcard'][$this->field]['rewrite'] = $this->rewrite;
|
$query['wildcard'][$this->field]['rewrite'] = $this->rewrite;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,22 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Exceptions;
|
namespace Blomstra\Search\Exceptions;
|
||||||
|
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
class SeedingException extends \Exception
|
class SeedingException extends \Exception
|
||||||
{
|
{
|
||||||
|
public function __construct($message = '', public array $items, $code = 0, Throwable $previous = null)
|
||||||
public function __construct($message = "", public array $items, $code = 0, Throwable $previous = null)
|
|
||||||
{
|
{
|
||||||
parent::__construct($message, $code, $previous);
|
parent::__construct($message, $code, $previous);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Jobs;
|
namespace Blomstra\Search\Jobs;
|
||||||
|
|
||||||
use Elasticsearch\Client;
|
use Elasticsearch\Client;
|
||||||
|
|
@ -9,21 +19,23 @@ class DeletingJob extends Job
|
||||||
{
|
{
|
||||||
public function handle(Client $client)
|
public function handle(Client $client)
|
||||||
{
|
{
|
||||||
if ($this->models->isEmpty()) return;
|
if ($this->models->isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Preparing body for storing.
|
// Preparing body for storing.
|
||||||
$body = $this->models->map(function (Model $model) {
|
$body = $this->models->map(function (Model $model) {
|
||||||
$document = $this->seeder->toDocument($model);
|
$document = $this->seeder->toDocument($model);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
['delete' => ['_index' => $this->index, '_id' => $document->id]]
|
['delete' => ['_index' => $this->index, '_id' => $document->id]],
|
||||||
];
|
];
|
||||||
})->flatten(1);
|
})->flatten(1);
|
||||||
|
|
||||||
$response = $client->bulk([
|
$response = $client->bulk([
|
||||||
'index' => $this->index,
|
'index' => $this->index,
|
||||||
'body' => $body->toArray(),
|
'body' => $body->toArray(),
|
||||||
'refresh' => true
|
'refresh' => true,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Jobs;
|
namespace Blomstra\Search\Jobs;
|
||||||
|
|
||||||
use Blomstra\Search\Seeders\Seeder;
|
use Blomstra\Search\Seeders\Seeder;
|
||||||
|
|
@ -16,6 +26,8 @@ abstract class Job extends AbstractJob
|
||||||
{
|
{
|
||||||
$this->index = resolve('blomstra.search.elastic_index');
|
$this->index = resolve('blomstra.search.elastic_index');
|
||||||
|
|
||||||
if (static::$onQueue) $this->onQueue(static::$onQueue);
|
if (static::$onQueue) {
|
||||||
|
$this->onQueue(static::$onQueue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Jobs;
|
namespace Blomstra\Search\Jobs;
|
||||||
|
|
||||||
use Blomstra\Search\Exceptions\SeedingException;
|
use Blomstra\Search\Exceptions\SeedingException;
|
||||||
|
|
@ -11,7 +21,9 @@ class SavingJob extends Job
|
||||||
{
|
{
|
||||||
public function handle(Client $client)
|
public function handle(Client $client)
|
||||||
{
|
{
|
||||||
if ($this->models->isEmpty()) return;
|
if ($this->models->isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Preparing body for storing.
|
// Preparing body for storing.
|
||||||
$body = $this->models->map(function (Model $model) {
|
$body = $this->models->map(function (Model $model) {
|
||||||
|
|
@ -19,18 +31,20 @@ class SavingJob extends Job
|
||||||
|
|
||||||
return [
|
return [
|
||||||
['index' => ['_index' => $this->index, '_id' => $document->id]],
|
['index' => ['_index' => $this->index, '_id' => $document->id]],
|
||||||
$document->toArray()
|
$document->toArray(),
|
||||||
];
|
];
|
||||||
})
|
})
|
||||||
->flatten(1);
|
->flatten(1);
|
||||||
|
|
||||||
$response = $client->bulk([
|
$response = $client->bulk([
|
||||||
'index' => $this->index,
|
'index' => $this->index,
|
||||||
'body' => $body->toArray(),
|
'body' => $body->toArray(),
|
||||||
'refresh' => true
|
'refresh' => true,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (Arr::get($response, 'errors') !== true) return true;
|
if (Arr::get($response, 'errors') !== true) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
$items = Arr::get($response, 'items');
|
$items = Arr::get($response, 'items');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,20 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search;
|
namespace Blomstra\Search;
|
||||||
|
|
||||||
use Blomstra\Search\Jobs\DeletingJob;
|
use Blomstra\Search\Jobs\DeletingJob;
|
||||||
use Blomstra\Search\Jobs\Job;
|
use Blomstra\Search\Jobs\Job;
|
||||||
use Blomstra\Search\Jobs\SavingJob;
|
use Blomstra\Search\Jobs\SavingJob;
|
||||||
use Blomstra\Search\Seeders;
|
|
||||||
use Elasticsearch\Client as Elastic;
|
use Elasticsearch\Client as Elastic;
|
||||||
use Elasticsearch\ClientBuilder;
|
use Elasticsearch\ClientBuilder;
|
||||||
use Flarum\Api\Client;
|
use Flarum\Api\Client;
|
||||||
|
|
@ -53,7 +62,6 @@ class Provider extends AbstractServiceProvider
|
||||||
return $builder->build();
|
return $builder->build();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
$this->container->instance(
|
$this->container->instance(
|
||||||
'blomstra.search.elastic_index',
|
'blomstra.search.elastic_index',
|
||||||
$settings->get('blomstra-search.elastic-index', 'flarum')
|
$settings->get('blomstra-search.elastic-index', 'flarum')
|
||||||
|
|
@ -62,19 +70,19 @@ class Provider extends AbstractServiceProvider
|
||||||
$this->container->extend(
|
$this->container->extend(
|
||||||
Client::class,
|
Client::class,
|
||||||
function () {
|
function () {
|
||||||
$pipe = new MiddlewarePipe;
|
$pipe = new MiddlewarePipe();
|
||||||
|
|
||||||
$exclude = resolve('flarum.api_client.exclude_middleware');
|
$exclude = resolve('flarum.api_client.exclude_middleware');
|
||||||
|
|
||||||
$middlewareStack = array_filter(resolve('flarum.api.middleware'), function ($middlewareClass) use ($exclude) {
|
$middlewareStack = array_filter(resolve('flarum.api.middleware'), function ($middlewareClass) use ($exclude) {
|
||||||
return ! in_array($middlewareClass, $exclude);
|
return !in_array($middlewareClass, $exclude);
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach ($middlewareStack as $middleware) {
|
foreach ($middlewareStack as $middleware) {
|
||||||
$pipe->pipe(resolve($middleware));
|
$pipe->pipe(resolve($middleware));
|
||||||
}
|
}
|
||||||
|
|
||||||
$pipe->pipe(new ExecuteRoute);
|
$pipe->pipe(new ExecuteRoute());
|
||||||
|
|
||||||
return new Api\Client($pipe);
|
return new Api\Client($pipe);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,29 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Save;
|
namespace Blomstra\Search\Save;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Support\Fluent;
|
use Illuminate\Support\Fluent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property string $type
|
* @property string $type
|
||||||
* @property string $id
|
* @property string $id
|
||||||
* @property string $content
|
* @property string $content
|
||||||
* @property Carbon $created_at
|
* @property Carbon $created_at
|
||||||
* @property Carbon $updated_at
|
* @property Carbon $updated_at
|
||||||
* @property int $user_id
|
* @property int $user_id
|
||||||
* @property bool $is_private
|
* @property bool $is_private
|
||||||
* @property bool $is_sticky
|
* @property bool $is_sticky
|
||||||
* @property array|int[] $groups
|
* @property array|int[] $groups
|
||||||
* @property array|int[] $recipient_groups
|
* @property array|int[] $recipient_groups
|
||||||
* @property array|int[] $recipient_users
|
* @property array|int[] $recipient_users
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Seeders;
|
namespace Blomstra\Search\Seeders;
|
||||||
|
|
||||||
use Blomstra\Search\Save\Document;
|
use Blomstra\Search\Save\Document;
|
||||||
|
|
@ -15,7 +25,7 @@ class CommentSeeder extends Seeder
|
||||||
{
|
{
|
||||||
public function type(): string
|
public function type(): string
|
||||||
{
|
{
|
||||||
return resolve(PostSerializer::class)->getType(new CommentPost);
|
return resolve(PostSerializer::class)->getType(new CommentPost());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function query(): Builder
|
public function query(): Builder
|
||||||
|
|
@ -53,21 +63,22 @@ class CommentSeeder extends Seeder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param CommentPost $model
|
* @param CommentPost $model
|
||||||
|
*
|
||||||
* @return Document
|
* @return Document
|
||||||
*/
|
*/
|
||||||
public function toDocument(Model $model): Document
|
public function toDocument(Model $model): Document
|
||||||
{
|
{
|
||||||
$document = new Document([
|
$document = new Document([
|
||||||
'type' => $this->type(),
|
'type' => $this->type(),
|
||||||
'id' => $this->type() . ':' . $model->id,
|
'id' => $this->type().':'.$model->id,
|
||||||
'content' => $model->content,
|
'content' => $model->content,
|
||||||
'content_partial' => $model->content,
|
'content_partial' => $model->content,
|
||||||
'created_at' => $model->created_at?->toAtomString(),
|
'created_at' => $model->created_at?->toAtomString(),
|
||||||
'updated_at' => $model->edited_at?->toAtomString(),
|
'updated_at' => $model->edited_at?->toAtomString(),
|
||||||
'is_private' => $model->is_private,
|
'is_private' => $model->is_private,
|
||||||
'user_id' => $model->user_id,
|
'user_id' => $model->user_id,
|
||||||
'groups' => $this->groupsForDiscussion($model->discussion),
|
'groups' => $this->groupsForDiscussion($model->discussion),
|
||||||
'comment_count' => $model->discussion->comment_count,
|
'comment_count' => $model->discussion->comment_count,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($this->extensionEnabled('fof-byobu')) {
|
if ($this->extensionEnabled('fof-byobu')) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Seeders;
|
namespace Blomstra\Search\Seeders;
|
||||||
|
|
||||||
use Blomstra\Search\Save\Document;
|
use Blomstra\Search\Save\Document;
|
||||||
|
|
@ -17,7 +27,7 @@ class DiscussionSeeder extends Seeder
|
||||||
{
|
{
|
||||||
public function type(): string
|
public function type(): string
|
||||||
{
|
{
|
||||||
return resolve(DiscussionSerializer::class)->getType(new Discussion);
|
return resolve(DiscussionSerializer::class)->getType(new Discussion());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function query(): Builder
|
public function query(): Builder
|
||||||
|
|
@ -32,6 +42,7 @@ class DiscussionSeeder extends Seeder
|
||||||
$includes[] = 'recipientUsers';
|
$includes[] = 'recipientUsers';
|
||||||
$includes[] = 'recipientGroups';
|
$includes[] = 'recipientGroups';
|
||||||
}
|
}
|
||||||
|
|
||||||
return Discussion::query()
|
return Discussion::query()
|
||||||
->whereNull('hidden_at')
|
->whereNull('hidden_at')
|
||||||
->with($includes);
|
->with($includes);
|
||||||
|
|
@ -53,21 +64,22 @@ class DiscussionSeeder extends Seeder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Discussion $model
|
* @param Discussion $model
|
||||||
|
*
|
||||||
* @return Document
|
* @return Document
|
||||||
*/
|
*/
|
||||||
public function toDocument(Model $model): Document
|
public function toDocument(Model $model): Document
|
||||||
{
|
{
|
||||||
$document = new Document([
|
$document = new Document([
|
||||||
'type' => $this->type(),
|
'type' => $this->type(),
|
||||||
'id' => $this->type() . ':' . $model->id,
|
'id' => $this->type().':'.$model->id,
|
||||||
'content' => $model->title,
|
'content' => $model->title,
|
||||||
'content_partial' => $model->title,
|
'content_partial' => $model->title,
|
||||||
'created_at' => $model->created_at?->toAtomString(),
|
'created_at' => $model->created_at?->toAtomString(),
|
||||||
'updated_at' => $model->last_posted_at?->toAtomString(),
|
'updated_at' => $model->last_posted_at?->toAtomString(),
|
||||||
'is_private' => $model->is_private,
|
'is_private' => $model->is_private,
|
||||||
'user_id' => $model->user_id,
|
'user_id' => $model->user_id,
|
||||||
'groups' => $this->groupsForDiscussion($model),
|
'groups' => $this->groupsForDiscussion($model),
|
||||||
'comment_count' => $model->comment_count,
|
'comment_count' => $model->comment_count,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($this->extensionEnabled('fof-byobu')) {
|
if ($this->extensionEnabled('fof-byobu')) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of blomstra/search.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Blomstra Ltd.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE.md
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Blomstra\Search\Seeders;
|
namespace Blomstra\Search\Seeders;
|
||||||
|
|
||||||
use Blomstra\Search\Save\Document;
|
use Blomstra\Search\Save\Document;
|
||||||
|
|
@ -20,6 +30,7 @@ abstract class Seeder
|
||||||
abstract public function query(): Builder;
|
abstract public function query(): Builder;
|
||||||
|
|
||||||
abstract public static function savingOn(Dispatcher $events, callable $callable);
|
abstract public static function savingOn(Dispatcher $events, callable $callable);
|
||||||
|
|
||||||
abstract public static function deletingOn(Dispatcher $events, callable $callable);
|
abstract public static function deletingOn(Dispatcher $events, callable $callable);
|
||||||
|
|
||||||
abstract public function toDocument(Model $model): Document;
|
abstract public function toDocument(Model $model): Document;
|
||||||
|
|
@ -56,7 +67,7 @@ abstract class Seeder
|
||||||
})->flatten();
|
})->flatten();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! $discussion->is_private && $permissions->isEmpty()) {
|
if (!$discussion->is_private && $permissions->isEmpty()) {
|
||||||
$permissions = $globalPermission;
|
$permissions = $globalPermission;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue