ldc-groupe/app/Traits/Models/HasMeilisearchIndex.php
2026-01-15 12:27:12 +01:00

113 lines
4.4 KiB
PHP

<?php
namespace App\Traits\Models;
use App\Models\SearchIndex;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
/**
* If there is a static function in a trait (named boot[TraitName]),
* it will be executed as the boot() function would on an Eloquent model.
* Futhermore, event in the Model observer doesn't erase actual events in the model,
* but adds them.
*/
trait HasMeilisearchIndex
{
/**
* Perform any actions required after the model boots.
*
* @return void
*/
public static function bootHasMeilisearchIndex(): void
{
$keyPrefix = Str::snake(class_basename(static::class));
$usesSoftDeletes = in_array(SoftDeletes::class, class_uses_recursive(static::class));
// Event executed avec saving a model.
static::saved(function ($model) use ($keyPrefix, $usesSoftDeletes) {
// Update ms index depending on status which is a global field non translatable.
$statusChanged = $model->wasChanged('status');
$originalLocale = app()->getLocale();
$locales = $statusChanged
? array_keys(LaravelLocalization::getSupportedLocales())
: [$originalLocale];
// Loop on all locales to update indexes when global fields like status is updated,
// Otherwise, on current locale.
collect($locales)->map(function($locale) use ($keyPrefix, $model, $usesSoftDeletes) {
// Set the locale to alter the right ms index.
app()->setLocale($locale);
$indexId = "{$keyPrefix}_{$model->getKey()}";
// Remove model from meilisearch index.
if ($usesSoftDeletes && method_exists($model, 'trashed') && $model->trashed()) {
SearchIndex::make([
'type' => $keyPrefix,
'model_id' => $model->getKey(),
])->unsearchable();
return;
}
$msIndex = $model->toSearchDocument();
// Add model to the meilisearch index if conditions are true, remove from it if not.
if ($msIndex) {
$msIndex->searchable();
} else {
SearchIndex::make([
'type' => $keyPrefix,
'model_id' => $model->getKey(),
])->unsearchable();
}
});
// Reset the locale with the original.
app()->setLocale($originalLocale);
});
static::deleted(function ($model) use ($keyPrefix) {
$originalLocale = app()->getLocale();
$locales = array_keys(LaravelLocalization::getSupportedLocales());
// Loop on all locales to update indexes when model is deleted (softdeleted or not).
collect($locales)->map(function($locale) use ($keyPrefix, $model) {
// Set the locale to alter the right ms index.
app()->setLocale($locale);
$indexId = "{$keyPrefix}_{$model->getKey()}";
// Remove model from meilisearch index.
SearchIndex::make([
'type' => $keyPrefix,
'model_id' => $model->getKey(),
])->unsearchable();
});
// Reset the locale with the original.
app()->setLocale($originalLocale);
});
if ($usesSoftDeletes) {
static::restored(function ($model) {
$originalLocale = app()->getLocale();
$locales = array_keys(LaravelLocalization::getSupportedLocales());
// Loop on all locales to update indexes when model is restored.
collect($locales)->map(function($locale) use ($model) {
// Set the locale to alter the right ms index.
app()->setLocale($locale);
// Add model to the meilisearch index if conditions are true.
$msIndex = $model->toSearchDocument();
if ($msIndex) {
$msIndex->searchable();
}
});
// Reset the locale with the original.
app()->setLocale($originalLocale);
});
}
}
}