feat: meilisearch
This commit is contained in:
parent
da3068f95e
commit
df3c300155
|
|
@ -40,6 +40,12 @@ QUEUE_CONNECTION=database
|
||||||
CACHE_STORE=database
|
CACHE_STORE=database
|
||||||
# CACHE_PREFIX=
|
# CACHE_PREFIX=
|
||||||
|
|
||||||
|
SCOUT_DRIVER=meilisearch
|
||||||
|
SCOUT_QUEUE=false
|
||||||
|
MEILISEARCH_HOST=http://meilisearch:7700
|
||||||
|
MEILISEARCH_KEY=masterKey
|
||||||
|
MEILISEARCH_PORT=7700
|
||||||
|
|
||||||
MEMCACHED_HOST=127.0.0.1
|
MEMCACHED_HOST=127.0.0.1
|
||||||
|
|
||||||
REDIS_CLIENT=phpredis
|
REDIS_CLIENT=phpredis
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,13 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\StoreHuntRequest;
|
||||||
|
use App\Http\Requests\UpdateHuntRequest;
|
||||||
use App\Models\Hunts;
|
use App\Models\Hunts;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class HuntsController extends Controller
|
class HuntsController extends Controller
|
||||||
|
|
@ -11,75 +16,31 @@ class HuntsController extends Controller
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
public function index(Request $request)
|
public function index(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$query = Hunts::with('participants:id,avatar_uri');
|
$searchTerm = $this->resolveSearchTerm($request);
|
||||||
|
|
||||||
if ($request->has('participating')) {
|
if ($searchTerm !== null) {
|
||||||
$participating = filter_var(
|
$hunts = Hunts::search($searchTerm)
|
||||||
$request->query('participating'),
|
->query(fn (Builder $query) => $this->applyHuntFilters(
|
||||||
FILTER_VALIDATE_BOOLEAN,
|
$query->with('participants:id,avatar_uri'),
|
||||||
FILTER_NULL_ON_FAILURE
|
$request
|
||||||
);
|
))
|
||||||
|
->paginate(10);
|
||||||
|
|
||||||
$userId = auth('sanctum')->id();
|
return response()->json($hunts);
|
||||||
|
|
||||||
Log::info('Participating filter resolved', [
|
|
||||||
'participating' => $participating,
|
|
||||||
'user_id' => $userId,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (! $userId) {
|
|
||||||
// Non connecté → aucune hunt "participating"
|
|
||||||
if ($participating === true) {
|
|
||||||
$query->whereRaw('1 = 0');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ($participating === true) {
|
|
||||||
// Hunts où l'utilisateur participe
|
|
||||||
$query->whereHas('participants', function ($q) use ($userId) {
|
|
||||||
$q->where('user_id', $userId);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Hunts où l'utilisateur NE participe PAS
|
|
||||||
$query->whereDoesntHave('participants', function ($q) use ($userId) {
|
|
||||||
$q->where('user_id', $userId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filtre active/inactive uniquement si le param est présent
|
$query = $this->applyHuntFilters(
|
||||||
if ($request->has('active')) {
|
Hunts::with('participants:id,avatar_uri'),
|
||||||
$now = \Illuminate\Support\Carbon::now();
|
$request
|
||||||
$active = filter_var($request->query('active'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
|
);
|
||||||
|
|
||||||
if ($active === true) {
|
|
||||||
// Actives: start_at <= now AND (end_at is null OR end_at >= now)
|
|
||||||
$query->where('start_at', '<=', $now)
|
|
||||||
->where(function ($q) use ($now) {
|
|
||||||
$q->whereNull('end_at')
|
|
||||||
->orWhere('end_at', '>=', $now);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Inactives: NOT(active)
|
|
||||||
$query->where(function ($q) use ($now) {
|
|
||||||
$q->whereNull('start_at')
|
|
||||||
->orWhere('start_at', '>', $now)
|
|
||||||
->orWhere(function ($q2) use ($now) {
|
|
||||||
$q2->whereNotNull('end_at')
|
|
||||||
->where('end_at', '<', $now);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$hunts = $query->paginate(10);
|
$hunts = $query->paginate(10);
|
||||||
|
|
||||||
return response()->json($hunts);
|
return response()->json($hunts);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
} catch (\Exception $e) {
|
|
||||||
Log::error('Error fetching hunts: '.$e->getMessage());
|
Log::error('Error fetching hunts: '.$e->getMessage());
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|
@ -89,10 +50,81 @@ class HuntsController extends Controller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function applyHuntFilters(Builder $query, Request $request): Builder
|
||||||
|
{
|
||||||
|
if ($request->has('participating')) {
|
||||||
|
$participating = filter_var(
|
||||||
|
$request->query('participating'),
|
||||||
|
FILTER_VALIDATE_BOOLEAN,
|
||||||
|
FILTER_NULL_ON_FAILURE
|
||||||
|
);
|
||||||
|
|
||||||
|
$userId = auth('sanctum')->id();
|
||||||
|
|
||||||
|
Log::info('Participating filter resolved', [
|
||||||
|
'participating' => $participating,
|
||||||
|
'user_id' => $userId,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (! $userId) {
|
||||||
|
if ($participating === true) {
|
||||||
|
$query->whereRaw('1 = 0');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($participating === true) {
|
||||||
|
$query->whereHas('participants', function ($q) use ($userId) {
|
||||||
|
$q->where('user_id', $userId);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$query->whereDoesntHave('participants', function ($q) use ($userId) {
|
||||||
|
$q->where('user_id', $userId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('active')) {
|
||||||
|
$now = Carbon::now();
|
||||||
|
$active = filter_var($request->query('active'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
|
||||||
|
|
||||||
|
if ($active === true) {
|
||||||
|
$query->where('start_at', '<=', $now)
|
||||||
|
->where(function ($q) use ($now) {
|
||||||
|
$q->whereNull('end_at')
|
||||||
|
->orWhere('end_at', '>=', $now);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$query->where(function ($q) use ($now) {
|
||||||
|
$q->whereNull('start_at')
|
||||||
|
->orWhere('start_at', '>', $now)
|
||||||
|
->orWhere(function ($q2) use ($now) {
|
||||||
|
$q2->whereNotNull('end_at')
|
||||||
|
->where('end_at', '<', $now);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function resolveSearchTerm(Request $request): ?string
|
||||||
|
{
|
||||||
|
$searchTerm = $request->query('search') ?? $request->query('q');
|
||||||
|
|
||||||
|
if (! is_string($searchTerm)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$searchTerm = trim($searchTerm);
|
||||||
|
|
||||||
|
return $searchTerm !== '' ? $searchTerm : null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store a newly created resource in storage.
|
* Store a newly created resource in storage.
|
||||||
*/
|
*/
|
||||||
public function store(\App\Http\Requests\StoreHuntRequest $request)
|
public function store(StoreHuntRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$validated = $request->validated();
|
$validated = $request->validated();
|
||||||
|
|
||||||
|
|
@ -109,7 +141,7 @@ class HuntsController extends Controller
|
||||||
/**
|
/**
|
||||||
* Display the specified resource.
|
* Display the specified resource.
|
||||||
*/
|
*/
|
||||||
public function show(Request $request, $id)
|
public function show(Request $request, int $id): JsonResponse
|
||||||
{
|
{
|
||||||
$hunt = Hunts::with(['steps', 'participants:id,avatar_uri'])->find($id);
|
$hunt = Hunts::with(['steps', 'participants:id,avatar_uri'])->find($id);
|
||||||
|
|
||||||
|
|
@ -160,7 +192,7 @@ class HuntsController extends Controller
|
||||||
return response()->json($hunt);
|
return response()->json($hunt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function participate(Request $request, $id)
|
public function participate(Request $request, int $id): JsonResponse
|
||||||
{
|
{
|
||||||
$hunt = Hunts::findOrFail($id);
|
$hunt = Hunts::findOrFail($id);
|
||||||
$user = $request->user();
|
$user = $request->user();
|
||||||
|
|
@ -174,7 +206,7 @@ class HuntsController extends Controller
|
||||||
return response()->json(['message' => 'Participation started'], 201);
|
return response()->json(['message' => 'Participation started'], 201);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function unparticipate(Request $request, $id)
|
public function unparticipate(Request $request, int $id): JsonResponse
|
||||||
{
|
{
|
||||||
$hunt = Hunts::findOrFail($id);
|
$hunt = Hunts::findOrFail($id);
|
||||||
$user = $request->user();
|
$user = $request->user();
|
||||||
|
|
@ -191,7 +223,7 @@ class HuntsController extends Controller
|
||||||
/**
|
/**
|
||||||
* Update the specified resource in storage.
|
* Update the specified resource in storage.
|
||||||
*/
|
*/
|
||||||
public function update(\App\Http\Requests\UpdateHuntRequest $request, $id)
|
public function update(UpdateHuntRequest $request, int $id): JsonResponse
|
||||||
{
|
{
|
||||||
$hunt = Hunts::find($id);
|
$hunt = Hunts::find($id);
|
||||||
|
|
||||||
|
|
@ -209,7 +241,7 @@ class HuntsController extends Controller
|
||||||
/**
|
/**
|
||||||
* Remove the specified resource from storage.
|
* Remove the specified resource from storage.
|
||||||
*/
|
*/
|
||||||
public function destroy($id)
|
public function destroy(int $id): JsonResponse
|
||||||
{
|
{
|
||||||
$hunt = Hunts::find($id);
|
$hunt = Hunts::find($id);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,14 @@ use App\Enums\HuntDifficulty;
|
||||||
use App\Enums\HuntStatus;
|
use App\Enums\HuntStatus;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
use Laravel\Scout\Searchable;
|
||||||
|
|
||||||
class Hunts extends Model
|
class Hunts extends Model
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
use Searchable;
|
||||||
|
|
||||||
protected $table = 'hunts';
|
protected $table = 'hunts';
|
||||||
|
|
||||||
|
|
@ -42,15 +46,48 @@ class Hunts extends Model
|
||||||
'difficulty' => HuntDifficulty::class,
|
'difficulty' => HuntDifficulty::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
public function steps()
|
public function steps(): HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(HuntSteps::class, 'hunt_id');
|
return $this->hasMany(HuntSteps::class, 'hunt_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function participants()
|
public function participants(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(User::class, 'hunt_participants', 'hunt_id', 'user_id')
|
return $this->belongsToMany(User::class, 'hunt_participants', 'hunt_id', 'user_id')
|
||||||
->withPivot(['current_step_number', 'status'])
|
->withPivot(['current_step_number', 'status'])
|
||||||
->withTimestamps();
|
->withTimestamps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array{
|
||||||
|
* id: int,
|
||||||
|
* title: string,
|
||||||
|
* slug: string,
|
||||||
|
* description: string|null,
|
||||||
|
* city: string,
|
||||||
|
* status: string,
|
||||||
|
* difficulty: string,
|
||||||
|
* is_public: bool,
|
||||||
|
* start_at: string|null,
|
||||||
|
* end_at: string|null
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
public function toSearchableArray(): array
|
||||||
|
{
|
||||||
|
$status = $this->status instanceof HuntStatus ? $this->status->value : $this->status;
|
||||||
|
$difficulty = $this->difficulty instanceof HuntDifficulty ? $this->difficulty->value : $this->difficulty;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'title' => $this->title,
|
||||||
|
'slug' => $this->slug,
|
||||||
|
'description' => $this->description,
|
||||||
|
'city' => $this->city,
|
||||||
|
'status' => $status,
|
||||||
|
'difficulty' => $difficulty,
|
||||||
|
'is_public' => $this->is_public,
|
||||||
|
'start_at' => $this->start_at?->toAtomString(),
|
||||||
|
'end_at' => $this->end_at?->toAtomString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
14
compose.yaml
14
compose.yaml
|
|
@ -23,6 +23,7 @@ services:
|
||||||
- sail
|
- sail
|
||||||
depends_on:
|
depends_on:
|
||||||
- mysql
|
- mysql
|
||||||
|
- meilisearch
|
||||||
mysql:
|
mysql:
|
||||||
image: "mysql/mysql-server:8.0"
|
image: "mysql/mysql-server:8.0"
|
||||||
ports:
|
ports:
|
||||||
|
|
@ -59,6 +60,17 @@ services:
|
||||||
- sail
|
- sail
|
||||||
depends_on:
|
depends_on:
|
||||||
- mysql
|
- mysql
|
||||||
|
meilisearch:
|
||||||
|
image: "getmeili/meilisearch:v1.7"
|
||||||
|
ports:
|
||||||
|
- "${MEILISEARCH_PORT:-7700}:7700"
|
||||||
|
environment:
|
||||||
|
MEILI_MASTER_KEY: "${MEILISEARCH_KEY:-masterKey}"
|
||||||
|
MEILI_ENV: "development"
|
||||||
|
volumes:
|
||||||
|
- "sail-meilisearch:/meili_data"
|
||||||
|
networks:
|
||||||
|
- sail
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
sail:
|
sail:
|
||||||
|
|
@ -66,3 +78,5 @@ networks:
|
||||||
volumes:
|
volumes:
|
||||||
sail-mysql:
|
sail-mysql:
|
||||||
driver: local
|
driver: local
|
||||||
|
sail-meilisearch:
|
||||||
|
driver: local
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,12 @@
|
||||||
"dedoc/scramble": "^0.13.5",
|
"dedoc/scramble": "^0.13.5",
|
||||||
"fakerphp/faker": "^1.23",
|
"fakerphp/faker": "^1.23",
|
||||||
"filament/filament": "^4.0",
|
"filament/filament": "^4.0",
|
||||||
|
"http-interop/http-factory-guzzle": "*",
|
||||||
"laravel/framework": "^12.0",
|
"laravel/framework": "^12.0",
|
||||||
"laravel/sanctum": "^4.0",
|
"laravel/sanctum": "^4.0",
|
||||||
"laravel/tinker": "^2.10.1"
|
"laravel/scout": "*",
|
||||||
|
"laravel/tinker": "^2.10.1",
|
||||||
|
"meilisearch/meilisearch-php": "*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"laravel/boost": "^1.8",
|
"laravel/boost": "^1.8",
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "047de0487d6a961282c968d1142d9844",
|
"content-hash": "1b380d582f2a52b93929fa0d443b0384",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "anourvalar/eloquent-serialize",
|
"name": "anourvalar/eloquent-serialize",
|
||||||
|
|
@ -2162,6 +2162,64 @@
|
||||||
],
|
],
|
||||||
"time": "2025-08-22T14:27:06+00:00"
|
"time": "2025-08-22T14:27:06+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "http-interop/http-factory-guzzle",
|
||||||
|
"version": "1.2.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/http-interop/http-factory-guzzle.git",
|
||||||
|
"reference": "c2c859ceb05c3f42e710b60555f4c35b6a4a3995"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/http-interop/http-factory-guzzle/zipball/c2c859ceb05c3f42e710b60555f4c35b6a4a3995",
|
||||||
|
"reference": "c2c859ceb05c3f42e710b60555f4c35b6a4a3995",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"guzzlehttp/psr7": "^1.7||^2.0",
|
||||||
|
"php": ">=7.3",
|
||||||
|
"psr/http-factory": "^1.0"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"psr/http-factory-implementation": "^1.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"http-interop/http-factory-tests": "^0.9",
|
||||||
|
"phpunit/phpunit": "^9.5"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"guzzlehttp/psr7": "Includes an HTTP factory starting in version 2.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Http\\Factory\\Guzzle\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "http://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "An HTTP Factory using Guzzle PSR7",
|
||||||
|
"keywords": [
|
||||||
|
"factory",
|
||||||
|
"http",
|
||||||
|
"psr-17",
|
||||||
|
"psr-7"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/http-interop/http-factory-guzzle/issues",
|
||||||
|
"source": "https://github.com/http-interop/http-factory-guzzle/tree/1.2.1"
|
||||||
|
},
|
||||||
|
"time": "2025-12-15T11:28:16+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "kirschbaum-development/eloquent-power-joins",
|
"name": "kirschbaum-development/eloquent-power-joins",
|
||||||
"version": "4.2.11",
|
"version": "4.2.11",
|
||||||
|
|
@ -2567,6 +2625,86 @@
|
||||||
},
|
},
|
||||||
"time": "2025-07-09T19:45:24+00:00"
|
"time": "2025-07-09T19:45:24+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "laravel/scout",
|
||||||
|
"version": "v10.23.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/laravel/scout.git",
|
||||||
|
"reference": "fb6d94cfc5708e4202dc00d46e61af0b9f35b03c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/laravel/scout/zipball/fb6d94cfc5708e4202dc00d46e61af0b9f35b03c",
|
||||||
|
"reference": "fb6d94cfc5708e4202dc00d46e61af0b9f35b03c",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"illuminate/bus": "^9.0|^10.0|^11.0|^12.0",
|
||||||
|
"illuminate/contracts": "^9.0|^10.0|^11.0|^12.0",
|
||||||
|
"illuminate/database": "^9.0|^10.0|^11.0|^12.0",
|
||||||
|
"illuminate/http": "^9.0|^10.0|^11.0|^12.0",
|
||||||
|
"illuminate/pagination": "^9.0|^10.0|^11.0|^12.0",
|
||||||
|
"illuminate/queue": "^9.0|^10.0|^11.0|^12.0",
|
||||||
|
"illuminate/support": "^9.0|^10.0|^11.0|^12.0",
|
||||||
|
"php": "^8.0",
|
||||||
|
"symfony/console": "^6.0|^7.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"algolia/algoliasearch-client-php": "<3.2.0|>=5.0.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"algolia/algoliasearch-client-php": "^3.2|^4.0",
|
||||||
|
"meilisearch/meilisearch-php": "^1.0",
|
||||||
|
"mockery/mockery": "^1.0",
|
||||||
|
"orchestra/testbench": "^7.31|^8.36|^9.15|^10.8",
|
||||||
|
"php-http/guzzle7-adapter": "^1.0",
|
||||||
|
"phpstan/phpstan": "^1.10",
|
||||||
|
"typesense/typesense-php": "^4.9.3"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"algolia/algoliasearch-client-php": "Required to use the Algolia engine (^3.2).",
|
||||||
|
"meilisearch/meilisearch-php": "Required to use the Meilisearch engine (^1.0).",
|
||||||
|
"typesense/typesense-php": "Required to use the Typesense engine (^4.9)."
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"Laravel\\Scout\\ScoutServiceProvider"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "10.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Laravel\\Scout\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Taylor Otwell",
|
||||||
|
"email": "taylor@laravel.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Laravel Scout provides a driver based solution to searching your Eloquent models.",
|
||||||
|
"keywords": [
|
||||||
|
"algolia",
|
||||||
|
"laravel",
|
||||||
|
"search"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/laravel/scout/issues",
|
||||||
|
"source": "https://github.com/laravel/scout"
|
||||||
|
},
|
||||||
|
"time": "2025-12-16T15:43:03+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "laravel/serializable-closure",
|
"name": "laravel/serializable-closure",
|
||||||
"version": "v2.0.7",
|
"version": "v2.0.7",
|
||||||
|
|
@ -3572,6 +3710,86 @@
|
||||||
},
|
},
|
||||||
"time": "2025-07-25T09:04:22+00:00"
|
"time": "2025-07-25T09:04:22+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "meilisearch/meilisearch-php",
|
||||||
|
"version": "v1.16.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/meilisearch/meilisearch-php.git",
|
||||||
|
"reference": "f9f63e0e7d12ffaae54f7317fa8f4f4dfa8ae7b6"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/meilisearch/meilisearch-php/zipball/f9f63e0e7d12ffaae54f7317fa8f4f4dfa8ae7b6",
|
||||||
|
"reference": "f9f63e0e7d12ffaae54f7317fa8f4f4dfa8ae7b6",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-json": "*",
|
||||||
|
"php": "^7.4 || ^8.0",
|
||||||
|
"php-http/discovery": "^1.7",
|
||||||
|
"psr/http-client": "^1.0",
|
||||||
|
"symfony/polyfill-php81": "^1.33"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"http-interop/http-factory-guzzle": "^1.2.0",
|
||||||
|
"php-cs-fixer/shim": "^3.59.3",
|
||||||
|
"phpstan/phpstan": "^2.0",
|
||||||
|
"phpstan/phpstan-deprecation-rules": "^2.0",
|
||||||
|
"phpstan/phpstan-phpunit": "^2.0",
|
||||||
|
"phpstan/phpstan-strict-rules": "^2.0",
|
||||||
|
"phpunit/phpunit": "^9.5 || ^10.5",
|
||||||
|
"symfony/http-client": "^5.4|^6.0|^7.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"guzzlehttp/guzzle": "Use Guzzle ^7 as HTTP client",
|
||||||
|
"http-interop/http-factory-guzzle": "Factory for guzzlehttp/guzzle",
|
||||||
|
"symfony/http-client": "Use Symfony Http client"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"MeiliSearch\\": "src/",
|
||||||
|
"Meilisearch\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Clémentine Urquizar",
|
||||||
|
"email": "clementine@meilisearch.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Bruno Casali",
|
||||||
|
"email": "bruno@meilisearch.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Laurent Cazanove",
|
||||||
|
"email": "lau.cazanove@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Tomas Norkūnas",
|
||||||
|
"email": "norkunas.tom@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP wrapper for the Meilisearch API",
|
||||||
|
"keywords": [
|
||||||
|
"api",
|
||||||
|
"client",
|
||||||
|
"instant",
|
||||||
|
"meilisearch",
|
||||||
|
"php",
|
||||||
|
"search"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/meilisearch/meilisearch-php/issues",
|
||||||
|
"source": "https://github.com/meilisearch/meilisearch-php/tree/v1.16.1"
|
||||||
|
},
|
||||||
|
"time": "2025-09-18T10:15:45+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "monolog/monolog",
|
"name": "monolog/monolog",
|
||||||
"version": "3.9.0",
|
"version": "3.9.0",
|
||||||
|
|
@ -4373,6 +4591,85 @@
|
||||||
},
|
},
|
||||||
"time": "2025-09-24T15:06:41+00:00"
|
"time": "2025-09-24T15:06:41+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "php-http/discovery",
|
||||||
|
"version": "1.20.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-http/discovery.git",
|
||||||
|
"reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-http/discovery/zipball/82fe4c73ef3363caed49ff8dd1539ba06044910d",
|
||||||
|
"reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"composer-plugin-api": "^1.0|^2.0",
|
||||||
|
"php": "^7.1 || ^8.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"nyholm/psr7": "<1.0",
|
||||||
|
"zendframework/zend-diactoros": "*"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"php-http/async-client-implementation": "*",
|
||||||
|
"php-http/client-implementation": "*",
|
||||||
|
"psr/http-client-implementation": "*",
|
||||||
|
"psr/http-factory-implementation": "*",
|
||||||
|
"psr/http-message-implementation": "*"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"composer/composer": "^1.0.2|^2.0",
|
||||||
|
"graham-campbell/phpspec-skip-example-extension": "^5.0",
|
||||||
|
"php-http/httplug": "^1.0 || ^2.0",
|
||||||
|
"php-http/message-factory": "^1.0",
|
||||||
|
"phpspec/phpspec": "^5.1 || ^6.1 || ^7.3",
|
||||||
|
"sebastian/comparator": "^3.0.5 || ^4.0.8",
|
||||||
|
"symfony/phpunit-bridge": "^6.4.4 || ^7.0.1"
|
||||||
|
},
|
||||||
|
"type": "composer-plugin",
|
||||||
|
"extra": {
|
||||||
|
"class": "Http\\Discovery\\Composer\\Plugin",
|
||||||
|
"plugin-optional": true
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Http\\Discovery\\": "src/"
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"src/Composer/Plugin.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Márk Sági-Kazár",
|
||||||
|
"email": "mark.sagikazar@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations",
|
||||||
|
"homepage": "http://php-http.org",
|
||||||
|
"keywords": [
|
||||||
|
"adapter",
|
||||||
|
"client",
|
||||||
|
"discovery",
|
||||||
|
"factory",
|
||||||
|
"http",
|
||||||
|
"message",
|
||||||
|
"psr17",
|
||||||
|
"psr7"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/php-http/discovery/issues",
|
||||||
|
"source": "https://github.com/php-http/discovery/tree/1.20.0"
|
||||||
|
},
|
||||||
|
"time": "2024-10-02T11:20:13+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "phpoption/phpoption",
|
"name": "phpoption/phpoption",
|
||||||
"version": "1.9.4",
|
"version": "1.9.4",
|
||||||
|
|
@ -7221,6 +7518,86 @@
|
||||||
],
|
],
|
||||||
"time": "2025-01-02T08:10:11+00:00"
|
"time": "2025-01-02T08:10:11+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-php81",
|
||||||
|
"version": "v1.33.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-php81.git",
|
||||||
|
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
|
||||||
|
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"thanks": {
|
||||||
|
"url": "https://github.com/symfony/polyfill",
|
||||||
|
"name": "symfony/polyfill"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Php81\\": ""
|
||||||
|
},
|
||||||
|
"classmap": [
|
||||||
|
"Resources/stubs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nicolas Grekas",
|
||||||
|
"email": "p@tchwork.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"polyfill",
|
||||||
|
"portable",
|
||||||
|
"shim"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/polyfill-php81/tree/v1.33.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/nicolas-grekas",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-09-09T11:45:10+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php83",
|
"name": "symfony/polyfill-php83",
|
||||||
"version": "v1.33.0",
|
"version": "v1.33.0",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,210 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default Search Engine
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option controls the default search connection that gets used while
|
||||||
|
| using Laravel Scout. This connection is used when syncing all models
|
||||||
|
| to the search service. You should adjust this based on your needs.
|
||||||
|
|
|
||||||
|
| Supported: "algolia", "meilisearch", "typesense",
|
||||||
|
| "database", "collection", "null"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'driver' => env('SCOUT_DRIVER', 'meilisearch'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Index Prefix
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify a prefix that will be applied to all search index
|
||||||
|
| names used by Scout. This prefix may be useful if you have multiple
|
||||||
|
| "tenants" or applications sharing the same search infrastructure.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'prefix' => env('SCOUT_PREFIX', ''),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Queue Data Syncing
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option allows you to control if the operations that sync your data
|
||||||
|
| with your search engines are queued. When this is set to "true" then
|
||||||
|
| all automatic data syncing will get queued for better performance.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'queue' => env('SCOUT_QUEUE', false),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Database Transactions
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This configuration option determines if your data will only be synced
|
||||||
|
| with your search indexes after every open database transaction has
|
||||||
|
| been committed, thus preventing any discarded data from syncing.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'after_commit' => false,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Chunk Sizes
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| These options allow you to control the maximum chunk size when you are
|
||||||
|
| mass importing data into the search engine. This allows you to fine
|
||||||
|
| tune each of these chunk sizes based on the power of the servers.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'chunk' => [
|
||||||
|
'searchable' => 500,
|
||||||
|
'unsearchable' => 500,
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Soft Deletes
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option allows to control whether to keep soft deleted records in
|
||||||
|
| the search indexes. Maintaining soft deleted records can be useful
|
||||||
|
| if your application still needs to search for the records later.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'soft_delete' => false,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Identify User
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option allows you to control whether to notify the search engine
|
||||||
|
| of the user performing the search. This is sometimes useful if the
|
||||||
|
| engine supports any analytics based on this application's users.
|
||||||
|
|
|
||||||
|
| Supported engines: "algolia"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'identify' => env('SCOUT_IDENTIFY', false),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Algolia Configuration
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may configure your Algolia settings. Algolia is a cloud hosted
|
||||||
|
| search engine which works great with Scout out of the box. Just plug
|
||||||
|
| in your application ID and admin API key to get started searching.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'algolia' => [
|
||||||
|
'id' => env('ALGOLIA_APP_ID', ''),
|
||||||
|
'secret' => env('ALGOLIA_SECRET', ''),
|
||||||
|
'index-settings' => [
|
||||||
|
// 'users' => [
|
||||||
|
// 'searchableAttributes' => ['id', 'name', 'email'],
|
||||||
|
// 'attributesForFaceting'=> ['filterOnly(email)'],
|
||||||
|
// ],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Meilisearch Configuration
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may configure your Meilisearch settings. Meilisearch is an open
|
||||||
|
| source search engine with minimal configuration. Below, you can state
|
||||||
|
| the host and key information for your own Meilisearch installation.
|
||||||
|
|
|
||||||
|
| See: https://www.meilisearch.com/docs/learn/configuration/instance_options#all-instance-options
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'meilisearch' => [
|
||||||
|
'host' => env('MEILISEARCH_HOST', 'http://localhost:7700'),
|
||||||
|
'key' => env('MEILISEARCH_KEY'),
|
||||||
|
'index-settings' => [
|
||||||
|
// 'users' => [
|
||||||
|
// 'filterableAttributes'=> ['id', 'name', 'email'],
|
||||||
|
// ],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Typesense Configuration
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may configure your Typesense settings. Typesense is an open
|
||||||
|
| source search engine using minimal configuration. Below, you will
|
||||||
|
| state the host, key, and schema configuration for the instance.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'typesense' => [
|
||||||
|
'client-settings' => [
|
||||||
|
'api_key' => env('TYPESENSE_API_KEY', 'xyz'),
|
||||||
|
'nodes' => [
|
||||||
|
[
|
||||||
|
'host' => env('TYPESENSE_HOST', 'localhost'),
|
||||||
|
'port' => env('TYPESENSE_PORT', '8108'),
|
||||||
|
'path' => env('TYPESENSE_PATH', ''),
|
||||||
|
'protocol' => env('TYPESENSE_PROTOCOL', 'http'),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'nearest_node' => [
|
||||||
|
'host' => env('TYPESENSE_HOST', 'localhost'),
|
||||||
|
'port' => env('TYPESENSE_PORT', '8108'),
|
||||||
|
'path' => env('TYPESENSE_PATH', ''),
|
||||||
|
'protocol' => env('TYPESENSE_PROTOCOL', 'http'),
|
||||||
|
],
|
||||||
|
'connection_timeout_seconds' => env('TYPESENSE_CONNECTION_TIMEOUT_SECONDS', 2),
|
||||||
|
'healthcheck_interval_seconds' => env('TYPESENSE_HEALTHCHECK_INTERVAL_SECONDS', 30),
|
||||||
|
'num_retries' => env('TYPESENSE_NUM_RETRIES', 3),
|
||||||
|
'retry_interval_seconds' => env('TYPESENSE_RETRY_INTERVAL_SECONDS', 1),
|
||||||
|
],
|
||||||
|
// 'max_total_results' => env('TYPESENSE_MAX_TOTAL_RESULTS', 1000),
|
||||||
|
'model-settings' => [
|
||||||
|
// User::class => [
|
||||||
|
// 'collection-schema' => [
|
||||||
|
// 'fields' => [
|
||||||
|
// [
|
||||||
|
// 'name' => 'id',
|
||||||
|
// 'type' => 'string',
|
||||||
|
// ],
|
||||||
|
// [
|
||||||
|
// 'name' => 'name',
|
||||||
|
// 'type' => 'string',
|
||||||
|
// ],
|
||||||
|
// [
|
||||||
|
// 'name' => 'created_at',
|
||||||
|
// 'type' => 'int64',
|
||||||
|
// ],
|
||||||
|
// ],
|
||||||
|
// 'default_sorting_field' => 'created_at',
|
||||||
|
// ],
|
||||||
|
// 'search-parameters' => [
|
||||||
|
// 'query_by' => 'name'
|
||||||
|
// ],
|
||||||
|
// ],
|
||||||
|
],
|
||||||
|
'import_action' => env('TYPESENSE_IMPORT_ACTION', 'upsert'),
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
||||||
|
|
@ -16,8 +16,8 @@ class DatabaseSeeder extends Seeder
|
||||||
{
|
{
|
||||||
|
|
||||||
$this->call([
|
$this->call([
|
||||||
LevelSeeder::class,
|
|
||||||
BordeauxHuntsSeeder::class,
|
BordeauxHuntsSeeder::class,
|
||||||
|
LevelSeeder::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,9 @@ services:
|
||||||
APP_KEY: "${APP_KEY}"
|
APP_KEY: "${APP_KEY}"
|
||||||
APP_URL: "${APP_URL}"
|
APP_URL: "${APP_URL}"
|
||||||
APP_DEBUG: "false"
|
APP_DEBUG: "false"
|
||||||
|
SCOUT_DRIVER: "${SCOUT_DRIVER}"
|
||||||
|
MEILISEARCH_HOST: "${MEILISEARCH_HOST}"
|
||||||
|
MEILISEARCH_KEY: "${MEILISEARCH_KEY}"
|
||||||
DB_CONNECTION: "mysql"
|
DB_CONNECTION: "mysql"
|
||||||
DB_HOST: "mysql"
|
DB_HOST: "mysql"
|
||||||
DB_PORT: 3306
|
DB_PORT: 3306
|
||||||
|
|
@ -29,6 +32,9 @@ services:
|
||||||
APP_ENV: "production"
|
APP_ENV: "production"
|
||||||
APP_KEY: "${APP_KEY}"
|
APP_KEY: "${APP_KEY}"
|
||||||
APP_URL: "${APP_URL}"
|
APP_URL: "${APP_URL}"
|
||||||
|
SCOUT_DRIVER: "${SCOUT_DRIVER}"
|
||||||
|
MEILISEARCH_HOST: "${MEILISEARCH_HOST}"
|
||||||
|
MEILISEARCH_KEY: "${MEILISEARCH_KEY}"
|
||||||
|
|
||||||
DB_CONNECTION: "mysql"
|
DB_CONNECTION: "mysql"
|
||||||
DB_HOST: "mysql"
|
DB_HOST: "mysql"
|
||||||
|
|
@ -99,6 +105,17 @@ services:
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 10
|
retries: 10
|
||||||
start_period: 10s
|
start_period: 10s
|
||||||
|
meilisearch:
|
||||||
|
image: getmeili/meilisearch:v1.7
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
MEILI_MASTER_KEY: "${MEILISEARCH_KEY}"
|
||||||
|
MEILI_ENV: "production"
|
||||||
|
volumes:
|
||||||
|
- meilisearch-data:/meili_data
|
||||||
|
ports:
|
||||||
|
- "7700:7700"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
mysql-data:
|
mysql-data:
|
||||||
|
meilisearch-data:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Hunts;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
|
||||||
|
uses(RefreshDatabase::class);
|
||||||
|
|
||||||
|
it('filters hunts using the search parameter', function (string $param) {
|
||||||
|
config(['scout.driver' => 'collection']);
|
||||||
|
|
||||||
|
$user = User::factory()->create();
|
||||||
|
$matching = Hunts::factory()->create([
|
||||||
|
'title' => 'Chasse au tresor de Bordeaux',
|
||||||
|
'description' => 'Une aventure urbaine',
|
||||||
|
]);
|
||||||
|
$nonMatching = Hunts::factory()->create([
|
||||||
|
'title' => 'Parcours decouverte Lyon',
|
||||||
|
'description' => 'Balade tranquille',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $this->actingAs($user, 'sanctum')
|
||||||
|
->getJson("/api/hunts?{$param}=tresor");
|
||||||
|
|
||||||
|
$response->assertOk();
|
||||||
|
$huntIds = collect($response->json('data'))->pluck('id')->all();
|
||||||
|
|
||||||
|
expect($huntIds)
|
||||||
|
->toContain($matching->id)
|
||||||
|
->not->toContain($nonMatching->id);
|
||||||
|
})->with([
|
||||||
|
'search' => 'search',
|
||||||
|
'q' => 'q',
|
||||||
|
]);
|
||||||
Loading…
Reference in New Issue