55 lines
1.9 KiB
PHP
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'));
|
|
});
|
|
|
|
}
|
|
}
|