1: | <?php |
2: | |
3: | namespace Baril\Orderly; |
4: | |
5: | use Illuminate\Database\Eloquent\Collection as EloquentCollection; |
6: | use Illuminate\Support\Arr; |
7: | |
8: | class OrderableCollection extends EloquentCollection |
9: | { |
10: | public function saveOrder() |
11: | { |
12: | if ($this->isEmpty()) { |
13: | return $this; |
14: | } |
15: | |
16: | $instance = $this->first(); |
17: | $orderColumn = $instance->getOrderColumn(); |
18: | $groupColumn = $instance->getGroupColumn(); |
19: | |
20: | |
21: | if ($groupColumn) { |
22: | foreach ((array) $groupColumn as $column) { |
23: | if ($this->pluck($column)->unique()->count() > 1) { |
24: | throw new GroupException('All models must be in same group!'); |
25: | } |
26: | } |
27: | } |
28: | |
29: | |
30: | $positions = $this->pluck($orderColumn)->sort()->all(); |
31: | reset($positions); |
32: | |
33: | |
34: | $instance->getConnection()->transaction(function () use ($orderColumn, &$positions) { |
35: | $this->values()->each(function ($model) use ($orderColumn, &$positions) { |
36: | |
37: | $model->newQuery()->whereKey($model->getKey())->update([$orderColumn => current($positions)]); |
38: | $model->setAttribute($orderColumn, current($positions)); |
39: | next($positions); |
40: | }); |
41: | }); |
42: | |
43: | return $this; |
44: | } |
45: | |
46: | public function setOrder($ids) |
47: | { |
48: | $count = $this->count(); |
49: | $isList = Arr::isList($this->keys()->all()); |
50: | |
51: | return $this->sortBy(function ($item) use ($ids, $count) { |
52: | $index = array_search($item->getKey(), $ids); |
53: | return ($index === false) ? $count + $item->getPosition() : $index; |
54: | })->saveOrder()->when($isList, function ($orderedCollection) { |
55: | return $orderedCollection->values(); |
56: | }); |
57: | } |
58: | } |
59: | |