61 lines
1.5 KiB
PHP
61 lines
1.5 KiB
PHP
<?php
|
|
|
|
namespace App\Traits\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
trait Orderable
|
|
{
|
|
/**
|
|
* Returns the grouping field used for ordering.
|
|
* Returns null if the order is global
|
|
*
|
|
* @return string|null
|
|
*/
|
|
public function getOrderGroupField(): ?string
|
|
{
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* shifts down by 1 all elements positioned after the delete.
|
|
*
|
|
* @param Model $model
|
|
* @return void
|
|
*/
|
|
public static function setOrder(Model $model): void
|
|
{
|
|
$groupField = $model->getOrderGroupField();
|
|
$query = $model::query()->where('priority_order', '>', $model->priority_order);
|
|
|
|
if ($groupField) {
|
|
$query->where($groupField, $model->{$groupField});
|
|
}
|
|
|
|
$query->each(function (Model $item): void {
|
|
$item->priority_order -= 1;
|
|
$item->saveOrFail();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Assigns the next order value on creation.
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function bootOrderable(): void
|
|
{
|
|
static::creating(function (Model $model): void {
|
|
if (!$model->priority_order) {
|
|
$groupField = $model->getOrderGroupField();
|
|
$query = static::query();
|
|
|
|
if ($groupField) {
|
|
$query->where($groupField, $model->{$groupField});
|
|
}
|
|
|
|
$model->priority_order = ($query->max('priority_order') ?? 0) + 1;
|
|
}
|
|
});
|
|
}
|
|
}
|