Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix registering custom searchers, allow searchers without fulltext #2755

Merged
merged 11 commits into from
Apr 19, 2021
2 changes: 1 addition & 1 deletion src/Extend/SimpleFlarumSearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public function addSearchMutator($callback)
public function extend(Container $container, Extension $extension = null)
{
if (! is_null($this->fullTextGambit)) {
$container->resolving('flarum.simple_search.fulltext_gambits', function ($oldFulltextGambits) {
$container->extend('flarum.simple_search.fulltext_gambits', function ($oldFulltextGambits) {
$oldFulltextGambits[$this->searcher] = $this->fullTextGambit;

return $oldFulltextGambits;
Expand Down
19 changes: 12 additions & 7 deletions src/Search/SearchServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,24 @@ public function register()
*/
public function boot()
{
// The rest of these we can resolve in the when->needs->give callback,
// but we need to resolve at least one regardless so we know which
// searchers we need to register gambits for.
$fullTextGambits = $this->container->make('flarum.simple_search.fulltext_gambits');
$gambits = $this->container->make('flarum.simple_search.gambits');

foreach ($fullTextGambits as $searcher => $fullTextGambitClass) {
$searchers = array_merge([], array_keys($fullTextGambits), array_keys($gambits));

foreach ($searchers as $searcher) {
$this->container
->when($searcher)
->needs(GambitManager::class)
->give(function () use ($searcher, $fullTextGambitClass) {
->give(function () use ($searcher, $fullTextGambits, $gambits) {
$gambitManager = new GambitManager();
$gambitManager->setFulltextGambit($this->container->make($fullTextGambitClass));
foreach (Arr::get($this->container->make('flarum.simple_search.gambits'), $searcher, []) as $gambit) {

$fullTextGambitClass = Arr::get($fullTextGambits, $searcher);
if (isset($fullTextGambitClass)) {
$gambitManager->setFulltextGambit($this->container->make($fullTextGambitClass));
}

foreach (Arr::get($gambits, $searcher, []) as $gambit) {
$gambitManager->add($this->container->make($gambit));
}

Expand Down
70 changes: 70 additions & 0 deletions tests/integration/extenders/SimpleFlarumSearchTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@
use Carbon\Carbon;
use Flarum\Discussion\Search\DiscussionSearcher;
use Flarum\Extend;
use Flarum\Group\Group;
use Flarum\Query\QueryCriteria;
use Flarum\Search\AbstractRegexGambit;
use Flarum\Search\AbstractSearcher;
use Flarum\Search\GambitInterface;
use Flarum\Search\SearchState;
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase;
use Flarum\User\User;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Database\Eloquent\Builder;

class SimpleFlarumSearchTest extends TestCase
{
Expand Down Expand Up @@ -135,6 +139,56 @@ public function search_mutator_has_effect_if_added_with_invokable_class()

$this->assertEquals('[]', json_encode($this->searchDiscussions('in text', 5)));
}

/**
* @test
*/
public function cant_resolve_custom_searcher_without_fulltext_gambit()
{
$this->expectException(BindingResolutionException::class);

$this->app()->getContainer()->make(CustomSearcher::class);
}

/**
* @test
*/
public function can_resolve_custom_searcher_with_fulltext_gambit()
{
$this->extend(
(new Extend\SimpleFlarumSearch(CustomSearcher::class))->setFullTextGambit(CustomGambit::class)
);

$anExceptionWasThrown = false;

try {
$this->app()->getContainer()->make(CustomSearcher::class);
} catch (BindingResolutionException $e) {
$anExceptionWasThrown = true;
}

$this->assertFalse($anExceptionWasThrown);
}

/**
* @test
*/
public function can_resolve_custom_searcher_with_regular_gambit()
{
$this->extend(
(new Extend\SimpleFlarumSearch(CustomSearcher::class))->addGambit(CustomGambit::class)
);

$anExceptionWasThrown = false;

try {
$this->app()->getContainer()->make(CustomSearcher::class);
} catch (BindingResolutionException $e) {
$anExceptionWasThrown = true;
}

$this->assertFalse($anExceptionWasThrown);
}
}

class NoResultFullTextGambit implements GambitInterface
Expand Down Expand Up @@ -179,3 +233,19 @@ public function __invoke($search, $criteria)
$search->getQuery()->whereRaw('1=0');
}
}

class CustomSearcher extends AbstractSearcher
{
// This isn't actually used, we just need it to implement the abstract method.
protected function getQuery(User $actor): Builder
{
return Group::query();
}
}

class CustomGambit implements GambitInterface
{
public function apply(SearchState $search, $bit)
{
}
}