56 lines
1.3 KiB
PHP
56 lines
1.3 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;
|
|
}
|
|
|
|
/**
|
|
* Set order after the last element of the list.
|
|
*
|
|
* @param Model $model
|
|
* @param boolean $isDeletion
|
|
* @return void
|
|
*/
|
|
public static function setOrder(Model $model, bool $isDeletion = false): void
|
|
{
|
|
/** @phpstan-ignore-next-line */
|
|
$groupField = $model->getOrderGroupField();
|
|
$maxOrderQuery = $model::query();
|
|
|
|
if ($groupField) {
|
|
$maxOrderQuery->where($groupField, $model->{$groupField});
|
|
}
|
|
|
|
$maxOrder = \intval($maxOrderQuery->max('order'));
|
|
|
|
if ($isDeletion) {
|
|
$query = $model::query()
|
|
->whereKeyNot($model)
|
|
/** @phpstan-ignore-next-line */
|
|
->whereBetween('order', [$model->order, $maxOrder]);
|
|
|
|
if ($groupField) {
|
|
$query->where($groupField, $model->{$groupField});
|
|
}
|
|
|
|
$query->decrement('order', 1);
|
|
return;
|
|
}
|
|
|
|
/** @phpstan-ignore-next-line */
|
|
$model->order = $maxOrder + 1;
|
|
}
|
|
}
|