ldc-boutique-cnc-sable/app/Traits/Controllers/HasMassActions.php
2026-10-27 09:58:12 +01:00

116 lines
4.2 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Traits\Controllers;
use App\Http\Requests\Bo\MassActionRequest;
use App\Interfaces\ModelWithStar;
use App\Interfaces\ModelWithStatus;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
use Throwable;
use UnexpectedValueException;
/**
* This trait works with Route::bind in App service provider
* to resolve the model and the DB row
* It does not work with binder Service
*
* @mixin \Illuminate\Routing\Controller
* @mixin \App\Interfaces\MassActions
*/
trait HasMassActions
{
/** Toggles model status */
public function massActions(MassActionRequest $request): RedirectResponse
{
try {
return DB::transaction(function () use ($request) {
$action = $request->string('action')->toString();
$modelKeyList = $request->array('models');
$modelClass = $this->getModelClass();
$model = new $modelClass();
$message = trans('crud.messages.action_done');
throw_if(
in_array($action, ['star', 'unstar']) && ! $model instanceof ModelWithStar,
UnexpectedValueException::class,
'Model does not implement ' . ModelWithStar::class
);
throw_if(
in_array($action, ['publish', 'unpublish']) && ! $model instanceof ModelWithStatus,
UnexpectedValueException::class,
'Model does not implement ' . ModelWithStatus::class
);
$foundModels = $model::query()
->whereIn($model->getKeyName(), $modelKeyList)
->get();
foreach ($foundModels as $foundModel) {
switch ($action) {
case 'star':
/** @var ModelWithStar&\Illuminate\Database\Eloquent\Model $foundModel */
$this->star($foundModel);
$message = trans('crud.messages.star_saved');
break;
case 'unstar':
/** @var ModelWithStar&\Illuminate\Database\Eloquent\Model $foundModel */
$this->unstar($foundModel);
$message = trans('crud.messages.star_saved');
break;
case 'publish':
/** @var ModelWithStatus&\Illuminate\Database\Eloquent\Model $foundModel */
$this->publish($foundModel);
$message = trans('crud.messages.publish_status_saved');
break;
case 'unpublish':
/** @var ModelWithStatus&\Illuminate\Database\Eloquent\Model $foundModel */
$this->unpublish($foundModel);
$message = trans('crud.messages.publish_status_saved');
break;
default:
throw ValidationException::withMessages([
'action' => trans('Bad Request'),
]);
}
$foundModel->saveOrFail();
}
return back()->with('info', $message);
});
} catch (ValidationException $e) {
throw $e;
} catch (Throwable) {
return back()->with('error', trans('crud.messages.cannot_be_updated'));
}
}
protected function star(ModelWithStar $model): void
{
$this->authorize('toggleStar', $model);
$model->setStar(true);
}
protected function unstar(ModelWithStar $model): void
{
$this->authorize('toggleStar', $model);
$model->setStar(false);
}
protected function publish(ModelWithStatus $model): void
{
$this->authorize('toggleStatus', $model);
$model->setStatus(true);
}
protected function unpublish(ModelWithStatus $model): void
{
$this->authorize('toggleStatus', $model);
$model->setStatus(false);
}
}