Skip to content

Commit 3325d21

Browse files
committed
WIP
1 parent c404a94 commit 3325d21

File tree

6 files changed

+131
-12
lines changed

6 files changed

+131
-12
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
],
1818
"require": {
1919
"php": "^8.0|^8.1",
20-
"illuminate/support": "^8.67"
20+
"illuminate/support": "^8.79"
2121
},
2222
"require-dev": {
2323
"mockery/mockery": "^1.3.3",

src/ModelToSearchThrough.php

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,32 @@ class ModelToSearchThrough
2929
*/
3030
protected int $key;
3131

32+
/**
33+
* Full-text search.
34+
*/
35+
protected bool $fullText;
36+
37+
/**
38+
* Full-text search options
39+
*/
40+
protected array $fullTextOptions = [];
41+
3242
/**
3343
* @param \Illuminate\Database\Eloquent\Builder $builder
3444
* @param \Illuminate\Support\Collection $columns
3545
* @param string $orderByColumn
3646
* @param integer $key
47+
* @param bool $fullText
48+
* @param array $fullTextOptions
3749
*/
38-
public function __construct(Builder $builder, Collection $columns, string $orderByColumn, int $key)
50+
public function __construct(Builder $builder, Collection $columns, string $orderByColumn, int $key, bool $fullText = false, array $fullTextOptions = [])
3951
{
40-
$this->builder = $builder;
41-
$this->columns = $columns;
42-
$this->orderByColumn = $orderByColumn;
43-
$this->key = $key;
52+
$this->builder = $builder;
53+
$this->columns = $columns;
54+
$this->orderByColumn = $orderByColumn;
55+
$this->key = $key;
56+
$this->fullText = $fullText;
57+
$this->fullTextOptions = $fullTextOptions;
4458
}
4559

4660
/**
@@ -142,4 +156,24 @@ public function getQualifiedOrderByColumnName(): string
142156
{
143157
return $this->qualifyColumn($this->orderByColumn);
144158
}
159+
160+
/**
161+
* Full-text search.
162+
*
163+
* @return boolean
164+
*/
165+
public function searchFullText(): bool
166+
{
167+
return $this->fullText;
168+
}
169+
170+
/**
171+
* Full-text search options.
172+
*
173+
* @return array
174+
*/
175+
public function fullTextOptions(): array
176+
{
177+
return $this->fullTextOptions;
178+
}
145179
}

src/Searcher.php

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Illuminate\Database\Eloquent\Builder;
66
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
7+
use Illuminate\Database\Eloquent\Model;
78
use Illuminate\Database\Query\Builder as BaseBuilder;
89
use Illuminate\Database\Query\Builder as QueryBuilder;
910
use Illuminate\Database\Query\Grammars\MySqlGrammar;
@@ -12,7 +13,6 @@
1213
use Illuminate\Support\Collection;
1314
use Illuminate\Support\Facades\DB;
1415
use Illuminate\Support\Str;
15-
use Illuminate\Database\Eloquent\Model;
1616

1717
class Searcher
1818
{
@@ -56,6 +56,11 @@ class Searcher
5656
*/
5757
protected bool $ignoreCase = false;
5858

59+
/**
60+
* Raw input.
61+
*/
62+
protected ?string $rawTerms = null;
63+
5964
/**
6065
* Collection of search terms.
6166
*/
@@ -185,6 +190,7 @@ public function includeModelType(string $key = 'type'): self
185190
* @param \Illuminate\Database\Eloquent\Builder|string $query
186191
* @param string|array|\Illuminate\Support\Collection $columns
187192
* @param string $orderByColumn
193+
* @param bool $fullText
188194
* @return self
189195
*/
190196
public function add($query, $columns = null, string $orderByColumn = null): self
@@ -195,7 +201,25 @@ public function add($query, $columns = null, string $orderByColumn = null): self
195201
$builder,
196202
Collection::wrap($columns),
197203
$orderByColumn ?: $builder->getModel()->getUpdatedAtColumn(),
198-
$this->modelsToSearchThrough->count()
204+
$this->modelsToSearchThrough->count(),
205+
);
206+
207+
$this->modelsToSearchThrough->push($modelToSearchThrough);
208+
209+
return $this;
210+
}
211+
212+
public function addFullText($query, $columns = null, array $options = [], string $orderByColumn = null): self
213+
{
214+
$builder = is_string($query) ? $query::query() : $query;
215+
216+
$modelToSearchThrough = new ModelToSearchThrough(
217+
$builder,
218+
Collection::wrap($columns),
219+
$orderByColumn ?: $builder->getModel()->getUpdatedAtColumn(),
220+
$this->modelsToSearchThrough->count(),
221+
true,
222+
$options
199223
);
200224

201225
$this->modelsToSearchThrough->push($modelToSearchThrough);
@@ -363,6 +387,8 @@ public function parseTerms(string $terms, callable $callback = null): Collection
363387
*/
364388
protected function initializeTerms(string $terms): self
365389
{
390+
$this->rawTerms = $terms;
391+
366392
$terms = $this->parseTerm ? $this->parseTerms($terms) : $terms;
367393

368394
$this->termsWithoutWildcards = Collection::wrap($terms)->filter()->map(function ($term) {
@@ -398,10 +424,19 @@ public function addSearchQueryToBuilder(Builder $builder, ModelToSearchThrough $
398424
}
399425

400426
$builder->where(function (Builder $query) use ($modelToSearchThrough) {
427+
if ($modelToSearchThrough->searchFullText()) {
428+
return $this->addWhereTermsToQuery(
429+
$query,
430+
$modelToSearchThrough->getColumns()->map(fn ($column) => $modelToSearchThrough->qualifyColumn($column))->all(),
431+
true,
432+
$modelToSearchThrough->fullTextOptions()
433+
);
434+
}
435+
401436
$modelToSearchThrough->getColumns()->each(function ($column) use ($query, $modelToSearchThrough) {
402437
Str::contains($column, '.')
403-
? $this->addNestedRelationToQuery($query, $column)
404-
: $this->addWhereTermsToQuery($query, $modelToSearchThrough->qualifyColumn($column));
438+
? $this->addNestedRelationToQuery($query, $column, $modelToSearchThrough->searchFullText())
439+
: $this->addWhereTermsToQuery($query, $modelToSearchThrough->qualifyColumn($column), $modelToSearchThrough->searchFullText());
405440
});
406441
});
407442
}
@@ -432,11 +467,17 @@ private function addNestedRelationToQuery(Builder $query, string $nestedRelation
432467
* Adds an 'orWhere' clause to search for each term in the given column.
433468
*
434469
* @param \Illuminate\Database\Eloquent\Builder $builder
435-
* @param string $column
470+
* @param array|string $columns
471+
* @param bool $fullText
472+
* @param array $fullTextOptions
436473
* @return void
437474
*/
438-
private function addWhereTermsToQuery(Builder $query, string $column)
475+
private function addWhereTermsToQuery(Builder $query, $column, bool $fullText = false, array $fullTextOptions = [])
439476
{
477+
if ($fullText) {
478+
return $query->orWhereFullText($column, $this->rawTerms, $fullTextOptions);
479+
}
480+
440481
$column = $this->ignoreCase ? (new MySqlGrammar)->wrap($column) : $column;
441482

442483
$this->terms->each(function ($term) use ($query, $column) {

tests/Blog.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace ProtoneMedia\LaravelCrossEloquentSearch\Tests;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class Blog extends Model
8+
{
9+
}

tests/Page.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace ProtoneMedia\LaravelCrossEloquentSearch\Tests;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class Page extends Model
8+
{
9+
}

tests/create_tables.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,32 @@ public function up()
3636
$table->date('published_at')->nullable();
3737
$table->timestamps();
3838
});
39+
40+
Schema::create('blogs', function (Blueprint $table) {
41+
$table->bigIncrements('id');
42+
$table->string('title');
43+
$table->string('subtitle');
44+
$table->string('body');
45+
46+
$table->fullText('title');
47+
$table->fullText(['title', 'subtitle']);
48+
$table->fullText(['title', 'subtitle', 'body']);
49+
50+
$table->timestamps();
51+
});
52+
53+
Schema::create('pages', function (Blueprint $table) {
54+
$table->bigIncrements('id');
55+
$table->string('title');
56+
$table->string('subtitle');
57+
$table->string('body');
58+
59+
$table->fullText('title');
60+
$table->fullText(['title', 'subtitle']);
61+
$table->fullText(['title', 'subtitle', 'body']);
62+
63+
$table->timestamps();
64+
});
3965
}
4066
/**
4167
* Reverse the migrations.

0 commit comments

Comments
 (0)