From e86a06a769db2504ca565be9b28e2ded470e0342 Mon Sep 17 00:00:00 2001 From: marinusvanvelzen Date: Fri, 15 Nov 2024 16:29:44 +0100 Subject: [PATCH] refactor: adhere to max phpstan --- phpstan.neon.dist | 2 +- src/Commands/Index.php | 8 +++++++- src/Commands/IndexOne.php | 13 ++++++++++++- src/Commands/UnindexOne.php | 13 ++++++++++++- src/IndexedRecord.php | 2 +- src/Indexer.php | 25 +++++++++++++++++++------ src/ModelObserver.php | 2 +- src/Search.php | 13 +++++++++---- src/TermBuilder.php | 4 ++-- 9 files changed, 64 insertions(+), 18 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 61c038f..02fbebb 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -4,4 +4,4 @@ parameters: - src/ # Level 10 is the highest level - level: 6 + level: max diff --git a/src/Commands/Index.php b/src/Commands/Index.php index 11f9186..0b66665 100644 --- a/src/Commands/Index.php +++ b/src/Commands/Index.php @@ -3,6 +3,7 @@ namespace Swis\Laravel\Fulltext\Commands; use Illuminate\Console\Command; +use InvalidArgumentException; use Swis\Laravel\Fulltext\Indexer; class Index extends Command @@ -21,8 +22,13 @@ class Index extends Command */ public function handle(): int { + $modelClass = $this->argument('model_class'); + if (!is_string($modelClass)) { + throw new InvalidArgumentException('Model class must be a string'); + } + $indexer = new Indexer; - $indexer->indexAllByClass($this->argument('model_class')); + $indexer->indexAllByClass($modelClass); return self::SUCCESS; } diff --git a/src/Commands/IndexOne.php b/src/Commands/IndexOne.php index 7bd9551..dc650e5 100644 --- a/src/Commands/IndexOne.php +++ b/src/Commands/IndexOne.php @@ -3,6 +3,7 @@ namespace Swis\Laravel\Fulltext\Commands; use Illuminate\Console\Command; +use InvalidArgumentException; use Swis\Laravel\Fulltext\Indexer; class IndexOne extends Command @@ -21,8 +22,18 @@ class IndexOne extends Command */ public function handle(): int { + $modelClass = $this->argument('model_class'); + if (!is_string($modelClass)) { + throw new InvalidArgumentException('Model class must be a string'); + } + + $id = $this->argument('id'); + if (!is_string($id)) { + throw new InvalidArgumentException('ID must be a string or an integer'); + } + $indexer = new Indexer; - $indexer->indexOneByClass($this->argument('model_class'), $this->argument('id')); + $indexer->indexOneByClass($modelClass, $id); return self::SUCCESS; } diff --git a/src/Commands/UnindexOne.php b/src/Commands/UnindexOne.php index b82b391..4b28b4d 100644 --- a/src/Commands/UnindexOne.php +++ b/src/Commands/UnindexOne.php @@ -3,6 +3,7 @@ namespace Swis\Laravel\Fulltext\Commands; use Illuminate\Console\Command; +use InvalidArgumentException; use Swis\Laravel\Fulltext\Indexer; class UnindexOne extends Command @@ -21,8 +22,18 @@ class UnindexOne extends Command */ public function handle(): int { + $modelClass = $this->argument('model_class'); + if (!is_string($modelClass)) { + throw new InvalidArgumentException('Model class must be a string'); + } + + $id = $this->argument('id'); + if (!is_string($id)) { + throw new InvalidArgumentException('ID must be a string or an integer'); + } + $indexer = new Indexer; - $indexer->unIndexOneByClass($this->argument('model_class'), $this->argument('id')); + $indexer->unIndexOneByClass($modelClass, $id); return self::SUCCESS; } diff --git a/src/IndexedRecord.php b/src/IndexedRecord.php index be51a60..1b83221 100644 --- a/src/IndexedRecord.php +++ b/src/IndexedRecord.php @@ -19,7 +19,7 @@ class IndexedRecord extends Model */ public function __construct(array $attributes = []) { - $this->connection = Config::get('laravel-fulltext.db_connection'); + $this->connection = Config::string('laravel-fulltext.db_connection'); parent::__construct($attributes); } diff --git a/src/Indexer.php b/src/Indexer.php index f392a6f..ab37b16 100644 --- a/src/Indexer.php +++ b/src/Indexer.php @@ -2,6 +2,7 @@ namespace Swis\Laravel\Fulltext; +use Illuminate\Database\Eloquent\Model; use Swis\Laravel\Fulltext\Contracts\Indexable; class Indexer @@ -13,8 +14,13 @@ public function indexModel(Indexable $indexable): void public function unIndexOneByClass(string $class, string|int $id): void { + if (!is_subclass_of($class, Model::class)) { + return; + } + $record = IndexedRecord::query() - ->where('indexable_id', $id)->where('indexable_type', (new $class)->getMorphClass()); + ->where('indexable_id', $id) + ->where('indexable_type', (new $class)->getMorphClass()); if ($record->exists()) { $record->delete(); @@ -23,20 +29,27 @@ public function unIndexOneByClass(string $class, string|int $id): void public function indexOneByClass(string $class, string|int $id): void { + if (!is_subclass_of($class, Model::class)) { + return; + } + $model = call_user_func([$class, 'find'], $id); - if (in_array(Indexable::class, class_uses($model), true)) { + if ($model instanceof Indexable) { $this->indexModel($model); } } public function indexAllByClass(string $class): void { + if (!is_subclass_of($class, Model::class)) { + return; + } + $model = new $class; - $self = $this; - if (in_array(Indexable::class, class_uses($model), true)) { - $model->chunk(100, function ($chunk) use ($self) { + if ($model instanceof Indexable) { + $model->newQuery()->chunk(100, function ($chunk) { foreach ($chunk as $modelRecord) { - $self->indexModel($modelRecord); + $this->indexModel($modelRecord); } }); } diff --git a/src/ModelObserver.php b/src/ModelObserver.php index 6e5889c..81e31d6 100644 --- a/src/ModelObserver.php +++ b/src/ModelObserver.php @@ -9,7 +9,7 @@ class ModelObserver /** * The class names that syncing is disabled for. * - * @var list + * @var array */ protected static array $syncingDisabledFor = []; diff --git a/src/Search.php b/src/Search.php index ca17b59..63859ff 100644 --- a/src/Search.php +++ b/src/Search.php @@ -3,6 +3,7 @@ namespace Swis\Laravel\Fulltext; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Config; @@ -17,6 +18,10 @@ public function run(string $search): Collection public function runForClass(string $search, string $class): Collection { + if (!is_subclass_of($class, Model::class)) { + return new Collection(); + } + $query = $this->searchQuery($search); $query->where('indexable_type', (new $class)->getMorphClass()); @@ -35,8 +40,8 @@ public function searchQuery(string $search): Builder $termsMatch = $terms->implode(' '); } - $titleWeight = str_replace(',', '.', sprintf('%f', Config::get('laravel-fulltext.weight.title', 1.5))); - $contentWeight = str_replace(',', '.', sprintf('%f', Config::get('laravel-fulltext.weight.content', 1.0))); + $titleWeight = str_replace(',', '.', sprintf('%f', Config::float('laravel-fulltext.weight.title', 1.5))); + $contentWeight = str_replace(',', '.', sprintf('%f', Config::float('laravel-fulltext.weight.content', 1.0))); $query = IndexedRecord::query() ->whereRaw('MATCH (indexed_title, indexed_content) AGAINST (? IN BOOLEAN MODE)', [$termsBool]) @@ -45,9 +50,9 @@ public function searchQuery(string $search): Builder '.$contentWeight.' * (MATCH (indexed_title, indexed_content) AGAINST (?)) ) DESC', [$termsMatch, $termsMatch]) - ->limit(Config::get('laravel-fulltext.limit-results')); + ->limit(Config::integer('laravel-fulltext.limit-results')); - if (Config::get('laravel-fulltext.exclude_feature_enabled')) { + if (Config::boolean('laravel-fulltext.exclude_feature_enabled')) { $query->with(['indexable' => function ($query) { $query->where(Config::get('laravel-fulltext.exclude_records_column_name'), '=', true); }]); diff --git a/src/TermBuilder.php b/src/TermBuilder.php index e0cf914..0de10f9 100644 --- a/src/TermBuilder.php +++ b/src/TermBuilder.php @@ -16,9 +16,9 @@ public static function terms(string $search): Collection // Remove every boolean operator (+, -, > <, ( ), ~, *, ", @distance) from the search query // else we will break the MySQL query. - $search = trim(preg_replace('/[+\-><\(\)~*\"@]+/', ' ', $search)); + $search = trim(preg_replace('/[+\-><\(\)~*\"@]+/', ' ', $search) ?: ''); - $terms = collect(preg_split('/[\s,]+/', $search))->filter(); + $terms = collect(preg_split('/[\s,]+/', $search) ?: [])->filter(); if ($wildcards === true) { $terms->transform(function ($term) {