Skip to content

Commit b675deb

Browse files
committed
wip
1 parent 7955973 commit b675deb

File tree

10 files changed

+377
-33
lines changed

10 files changed

+377
-33
lines changed

.vscode/extensions.json

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,5 @@
11
{
2-
"recommendations": [
3-
"DEVSENSE.phptools-vscode",
4-
"open-southeners.php-support-utils",
5-
"open-southeners.laravel-pint",
6-
"ikappas.composer",
7-
"pixelfear.composer-links",
8-
"editorconfig.editorconfig",
9-
"xdebug.php-debug",
10-
"junstyle.php-cs-fixer",
11-
"kasik96.latte",
12-
"calebporzio.better-phpunit"
13-
]
2+
"recommendations": [
3+
"open-southeners.vscode-php-extension-pack"
4+
]
145
}

composer.json

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,15 @@
2323
"illuminate/support": "^8.0|^9.0"
2424
},
2525
"require-dev": {
26+
"laravel/scout": "^9.0",
2627
"nunomaduro/larastan": "^1.0",
2728
"phpstan/phpstan": "^1.0",
2829
"phpunit/phpunit": "^7.0|^9.0",
2930
"orchestra/testbench": "^4.0|^6.0|^7.0"
3031
},
32+
"suggest": {
33+
"laravel/scout": "Laravel Scout for use with UnionBuilder::search() method"
34+
},
3135
"autoload": {
3236
"psr-4": {
3337
"OpenSoutheners\\LaravelEloquentUnionBuilder\\": "src"
@@ -41,12 +45,5 @@
4145
"config": {
4246
"sort-packages": true
4347
},
44-
"extra": {
45-
"laravel": {
46-
"providers": [
47-
"OpenSoutheners\\LaravelEloquentUnionBuilder\\ServiceProvider"
48-
]
49-
}
50-
},
5148
"minimum-stability": "dev"
5249
}

src/UnionBuilder.php

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

55
use Exception;
66
use Illuminate\Database\Eloquent\Builder;
7+
use Illuminate\Database\SQLiteConnection;
78
use Illuminate\Support\Arr;
89
use Illuminate\Support\Facades\DB;
910
use Illuminate\Support\Facades\Schema;
@@ -46,25 +47,30 @@ public function __construct(array $builders = [])
4647
* Make new instance of UnionBuilder by the following models classes.
4748
*
4849
* @param array<class-string<\Illuminate\Database\Eloquent\Model>> $models
49-
* @return UnionBuilder
50+
* @return \OpenSoutheners\LaravelEloquentUnionBuilder\UnionBuilder
5051
*/
5152
public static function from(array $models)
5253
{
53-
$builders = [];
54+
$unionBuilder = new static();
5455

55-
foreach ($models as $model) {
56-
$builders[$model] = $model::query();
56+
foreach ($models as $model => $columns) {
57+
if (is_numeric($model)) {
58+
$model = $columns;
59+
$columns = null;
60+
}
61+
62+
$unionBuilder->add($model::query());
5763
}
5864

59-
return new static($builders);
65+
return $unionBuilder;
6066
}
6167

6268
/**
6369
* Search by text content on the following models using Laravel Scout.
6470
*
6571
* @param string $searchQuery
6672
* @param array<class-string<\Illuminate\Database\Eloquent\Model>>|array<class-string<\Illuminate\Database\Eloquent\Model>, array> $models
67-
* @return UnionBuilder
73+
* @return \OpenSoutheners\LaravelEloquentUnionBuilder\UnionBuilder
6874
*/
6975
public static function search(string $searchQuery, array $models)
7076
{
@@ -76,7 +82,7 @@ public static function search(string $searchQuery, array $models)
7682
$columns = null;
7783
}
7884

79-
if (! class_use($model, Searchable::class)) {
85+
if (! in_array(Searchable::class, class_uses($model))) {
8086
throw new Exception("Model '${model}' does not use Laravel Scout.");
8187
}
8288

@@ -88,7 +94,7 @@ public static function search(string $searchQuery, array $models)
8894

8995
$unionBuilder->add(
9096
$model::query()->whereKey($modelSearchResultKeys->toArray()),
91-
$columns ?? Schema::getColumnListing($model::getTableName())
97+
$columns ?? Schema::getColumnListing((new $model)->getTable())
9298
);
9399
}
94100

@@ -121,10 +127,15 @@ private function getUnionBuilder()
121127

122128
foreach ($this->builders as $builder) {
123129
$model = get_class($builder->getModel());
124-
$modelSelectedColumns = $this->selectModelsColumns[$model];
130+
$modelSelectedColumns = $this->selectModelsColumns[$model]
131+
?? Schema::getColumnListing($builder->getModel()->getTable());
132+
133+
if (! ($builder->getConnection() instanceof SQLiteConnection)) {
134+
$model = str_replace('\\', '\\\\', $model);
135+
}
125136

126137
$selectColumnsArr = [];
127-
$selectColumnsArr[] = DB::raw("'".str_replace('\\', '\\\\', $model)."' as union_model_class");
138+
$selectColumnsArr[] = DB::raw("'".$model."' as union_model_class");
128139
$selectColumnsArr = array_merge(
129140
$selectColumnsArr,
130141
array_map(function ($item) use ($modelSelectedColumns) {
@@ -157,9 +168,9 @@ public function getAllSelectedColumns()
157168
/**
158169
* Add Eloquent query builder to this union builder selecting the following columns.
159170
*
160-
* @param Builder $builder
171+
* @param \Illuminate\Database\Eloquent\Builder $builder
161172
* @param array $columns
162-
* @return UnionBuilder
173+
* @return $this
163174
*/
164175
public function add(Builder $builder, array $columns = [])
165176
{

tests/Fixtures/Post.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace OpenSoutheners\LaravelEloquentUnionBuilder\Tests\Fixtures;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
use Laravel\Scout\Searchable;
7+
8+
class Post extends Model
9+
{
10+
use Searchable;
11+
12+
/**
13+
* The attributes that are mass assignable.
14+
*
15+
* @var array<string>
16+
*/
17+
protected $fillable = ['title', 'slug', 'content'];
18+
19+
/**
20+
* The attributes that should be hidden for serialization.
21+
*
22+
* @var array<string>
23+
*/
24+
protected $hidden = ['slug'];
25+
26+
/**
27+
* Get the indexable data array for the model.
28+
*
29+
* @return array
30+
*/
31+
public function toSearchableArray()
32+
{
33+
return [
34+
'id' => $this->id,
35+
'title' => $this->title,
36+
'slug' => $this->slug,
37+
'content' => $this->content,
38+
];
39+
}
40+
}

tests/Fixtures/Tag.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace OpenSoutheners\LaravelEloquentUnionBuilder\Tests\Fixtures;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
use Laravel\Scout\Searchable;
7+
8+
class Tag extends Model
9+
{
10+
use Searchable;
11+
12+
/**
13+
* The attributes that should be visible in serialization.
14+
*
15+
* @var string[]
16+
*/
17+
protected $visible = ['name', 'slug'];
18+
19+
/**
20+
* The attributes that aren't mass assignable.
21+
*
22+
* @var string[]
23+
*/
24+
protected $guarded = [];
25+
26+
/**
27+
* Get the indexable data array for the model.
28+
*
29+
* @return array
30+
*/
31+
public function toSearchableArray()
32+
{
33+
return [
34+
'id' => $this->id,
35+
'name' => $this->name,
36+
'slug' => $this->slug,
37+
];
38+
}
39+
}

tests/Fixtures/User.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
namespace OpenSoutheners\LaravelEloquentUnionBuilder\Tests\Fixtures;
4+
5+
use Illuminate\Foundation\Auth\User as Authenticatable;
6+
use Laravel\Scout\Searchable;
7+
8+
class User extends Authenticatable
9+
{
10+
use Searchable;
11+
12+
/**
13+
* The attributes that are mass assignable.
14+
*
15+
* @var string[]
16+
*/
17+
protected $fillable = ['id', 'name', 'email', 'password'];
18+
19+
/**
20+
* The attributes that should be visible in serialization.
21+
*
22+
* @var string[]
23+
*/
24+
protected $visible = ['name', 'email'];
25+
26+
/**
27+
* The attributes that should be hidden for serialization.
28+
*
29+
* @var array<int, string>
30+
*/
31+
protected $hidden = [
32+
'password',
33+
'remember_token',
34+
];
35+
36+
/**
37+
* The attributes that should be cast.
38+
*
39+
* @var array<string, string>
40+
*/
41+
protected $casts = [
42+
'email_verified_at' => 'datetime',
43+
];
44+
45+
/**
46+
* Get the indexable data array for the model.
47+
*
48+
* @return array
49+
*/
50+
public function toSearchableArray()
51+
{
52+
return [
53+
'id' => $this->id,
54+
'name' => $this->name,
55+
'email' => $this->email,
56+
];
57+
}
58+
}

tests/TestCase.php

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
namespace OpenSoutheners\LaravelEloquentUnionBuilder\Tests;
44

5-
use Orchestra\Testbench\TestCase as Orchestra;
5+
use Laravel\Scout\ScoutServiceProvider;
66
use OpenSoutheners\LaravelEloquentUnionBuilder\ServiceProvider;
7+
use Orchestra\Testbench\TestCase as Orchestra;
8+
use MeiliSearch\Contracts\TasksQuery;
9+
use Laravel\Scout\EngineManager;
710

811
abstract class TestCase extends Orchestra
912
{
@@ -16,7 +19,36 @@ abstract class TestCase extends Orchestra
1619
protected function getPackageProviders($app)
1720
{
1821
return [
19-
ServiceProvider::class,
22+
ScoutServiceProvider::class,
2023
];
2124
}
25+
26+
/**
27+
* Define environment setup.
28+
*
29+
* @param \Illuminate\Foundation\Application $app
30+
* @return void
31+
*/
32+
protected function defineEnvironment($app)
33+
{
34+
// Setup default database to use sqlite :memory:
35+
$app['config']->set('database.default', 'testing');
36+
$app['config']->set('scout.driver', 'collection');
37+
$app['config']->set('database.connections.testing', [
38+
'driver' => 'sqlite',
39+
'database' => ':memory:',
40+
'prefix' => '',
41+
]);
42+
}
43+
44+
/**
45+
* Define database migrations.
46+
*
47+
* @return void
48+
*/
49+
protected function defineDatabaseMigrations()
50+
{
51+
$this->loadLaravelMigrations();
52+
$this->loadMigrationsFrom(__DIR__.'/database');
53+
}
2254
}

0 commit comments

Comments
 (0)