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