Files

62 lines
2.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Scout;
use App\Enums\Http\Api\Paging\PaginationStrategy;
use App\Http\Api\Query\Query;
use App\Http\Api\Schema\EloquentSchema;
use App\Scout\Collection\CollectionSearch;
use App\Scout\Elasticsearch\Elasticsearch;
use App\Scout\Typesense\Typesense;
use Closure;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use RuntimeException;
abstract class Search
{
public function __construct(protected Criteria $criteria) {}
/**
* @param class-string<Model>|Model $model
*/
public static function getSearch(Model|string $model, Criteria $criteria): Search
{
$model = $model instanceof Model ? $model : new $model;
return match ($driver = Config::get('scout.driver')) {
'collection' => App::make(CollectionSearch::class, ['model' => $model, 'criteria' => $criteria]),
'elastic' => App::make(Elasticsearch::class, ['model' => $model, 'criteria' => $criteria]),
'typesense' => App::make(Typesense::class, ['model' => $model, 'criteria' => $criteria]),
default => throw new RuntimeException("Unsupported {$driver} search driver configured."),
};
}
/**
* Should the search be performed?
*/
abstract public function shouldSearch(): bool;
/**
* Perform the search.
*/
abstract public function searchViaJSONAPI(
Query $query,
EloquentSchema $schema,
PaginationStrategy $paginationStrategy
): Collection|Paginator;
/**
* @param Closure(EloquentBuilder): mixed $callback
* @param array<string, array{direction: string, isString: bool, relation: ?string}> $sorts
*/
abstract public function search(?Closure $callback = null, int $perPage = 15, int $page = 1, array $sorts = []): LengthAwarePaginator;
}