80 lines
2.3 KiB
PHP
80 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace App\Traits\Utilities;
|
|
|
|
trait WithSortOrder
|
|
{
|
|
/**
|
|
* Get the model class for this sortable entity
|
|
*/
|
|
abstract protected function getModelClass(): string;
|
|
|
|
/**
|
|
* Get the current model instance
|
|
*/
|
|
abstract protected function getModelInstance();
|
|
|
|
/**
|
|
* Adjust sort order after deletion
|
|
*/
|
|
protected function adjustSortOrderAfterDelete($deletedModel): void
|
|
{
|
|
$modelClass = $this->getModelClass();
|
|
|
|
$modelClass::where('sort_order', '>', $deletedModel->sort_order)
|
|
->orderBy('sort_order')
|
|
->get()
|
|
->each(function ($item) {
|
|
$item->update(['sort_order' => $item->sort_order - 1]);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Handle sort order changes (up, down, first, last)
|
|
*/
|
|
public function sortOrder(string $direction): void
|
|
{
|
|
$modelClass = $this->getModelClass();
|
|
$model = $this->getModelInstance();
|
|
|
|
if (in_array($direction, ['up', 'down'])) {
|
|
$swap = null;
|
|
|
|
if ($direction === 'up') {
|
|
$swap = $modelClass::where('sort_order', '<', $model->sort_order)
|
|
->orderByDesc('sort_order')
|
|
->first();
|
|
} else {
|
|
$swap = $modelClass::where('sort_order', '>', $model->sort_order)
|
|
->orderBy('sort_order')
|
|
->first();
|
|
}
|
|
|
|
if ($swap) {
|
|
$temp = $model->sort_order;
|
|
$model->update(['sort_order' => $swap->sort_order]);
|
|
$swap->update(['sort_order' => $temp]);
|
|
}
|
|
} elseif ($direction === 'first') {
|
|
$model->update(['sort_order' => $modelClass::min('sort_order') - 1]);
|
|
$this->normalizeSortOrder();
|
|
} elseif ($direction === 'last') {
|
|
$model->update(['sort_order' => $modelClass::max('sort_order') + 1]);
|
|
$this->normalizeSortOrder();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Normalize sort order to ensure consecutive numbering
|
|
*/
|
|
protected function normalizeSortOrder(): void
|
|
{
|
|
$modelClass = $this->getModelClass();
|
|
$items = $modelClass::orderBy('sort_order')->get();
|
|
|
|
foreach ($items as $index => $item) {
|
|
$item->update(['sort_order' => $index + 1]);
|
|
}
|
|
}
|
|
}
|