Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
96.30% |
26 / 27 |
|
50.00% |
1 / 2 |
CRAP | |
0.00% |
0 / 1 |
OrderableCollection | |
96.30% |
26 / 27 |
|
50.00% |
1 / 2 |
7 | |
0.00% |
0 / 1 |
saveOrder | |
94.74% |
18 / 19 |
|
0.00% |
0 / 1 |
5.00 | |||
setOrder | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
2 |
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 | // Check that all items are in the same group: |
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 | // Get current positions: |
30 | $positions = $this->pluck($orderColumn)->sort()->all(); |
31 | reset($positions); |
32 | |
33 | // Save the new order: |
34 | $instance->getConnection()->transaction(function () use ($orderColumn, &$positions) { |
35 | $this->values()->each(function ($model) use ($orderColumn, &$positions) { |
36 | // Update the order field without triggering the listeners: |
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 | } |