116 lines
4.2 KiB
PHP
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);
|
|
}
|
|
}
|