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 | } |