ldc-le-gaulois-pro/app/Traits/Controllers/ManagesOrder.php
2026-03-25 10:45:26 +01:00

55 lines
1.9 KiB
PHP

<?php
namespace App\Traits\Controllers;
use App\Http\Requests\Bo\UpdateOrderRequest;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\RedirectResponse;
trait ManagesOrder
{
/**
* Updates the order of a model and reorders all impacted elements.
*
* Shifts by +1 or -1 all elements located between the old
* and new position of the model, then assigns the new position
* to the target model. The whole operation runs inside a
* database transaction to ensure data consistency.
*
* @param UpdateOrderRequest $request The validated request containing the 'priority' field.
* @param Model $model The model to reorder (must use the Orderable trait).
* @return RedirectResponse
*
* @throws \Throwable Returns if save fail.
*/
public function changeOrderPriority(UpdateOrderRequest $request, Model $model): RedirectResponse
{
$newPriority = (int) $request->validated('priority_order');
return DB::transaction(function () use ($model, $newPriority): RedirectResponse {
$query = $model::query()
->whereKeyNot($model)
->whereBetween('priority_order', [
min($model->priority_order, $newPriority),
max($model->priority_order, $newPriority),
]);
$groupField = $model->getOrderGroupField();
if ($groupField) {
$query->where($groupField, $model->{$groupField});
}
$model->priority_order < $newPriority
? $query->decrement('priority_order', 1)
: $query->increment('priority_order', 1);
$model->priority_order = $newPriority;
$model->saveOrFail();
return redirect()->back()->with('success', trans('crud.messages.order_changed'));
});
}
}