Skip to content

Commit

Permalink
add move by
Browse files Browse the repository at this point in the history
  • Loading branch information
EriBloo committed Oct 16, 2023
1 parent a7b01a7 commit 9b4899e
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 0 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,13 @@ $myModel->moveOrderDown();
$myModel->moveOrderUp();
```

Or you can move model up or down by specific amount:

```php
$myModel->moveDownBy(6);
$myModel->moveUpBy(4);
```

You can also move a model to the first or last position:

```php
Expand Down
62 changes: 62 additions & 0 deletions src/SortableTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,68 @@ public function moveToStart(): static
return $this;
}

public function moveDownBy(int $amount): static
{
if ($amount < 1) {
return $this;
}

if ($amount === 1) {
return $this->moveOrderDown();
}

$orderColumnName = $this->determineOrderColumnName();

$newOrder = (int) $this->buildSortQuery()
->where($orderColumnName, '<=', $this->$orderColumnName + $amount)
->max($orderColumnName);

if ($this->$orderColumnName === $newOrder) {
return $this;
}

$oldOrder = $this->$orderColumnName;
$this->$orderColumnName = $newOrder;
$this->save();

$this->buildSortQuery()->where($this->getKeyName(), '!=', $this->getKey())
->whereBetween($orderColumnName, [$oldOrder, $newOrder])
->decrement($orderColumnName);

return $this;
}

public function moveUpBy(int $amount): static
{
if ($amount < 1) {
return $this;
}

if ($amount === 1) {
return $this->moveOrderUp();
}

$orderColumnName = $this->determineOrderColumnName();

$newOrder = (int) $this->buildSortQuery()
->where($orderColumnName, '>=', $this->$orderColumnName - $amount)
->min($orderColumnName);

if ($this->$orderColumnName === $newOrder) {
return $this;
}

$oldOrder = $this->$orderColumnName;
$this->$orderColumnName = $newOrder;
$this->save();

$this->buildSortQuery()->where($this->getKeyName(), '!=', $this->getKey())
->whereBetween($orderColumnName, [$newOrder, $oldOrder])
->increment($orderColumnName);

return $this;
}

public function moveToEnd(): static
{
$maxOrder = $this->getHighestOrderNumber();
Expand Down
48 changes: 48 additions & 0 deletions tests/SortableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -371,4 +371,52 @@ public function it_can_tell_if_element_is_last_in_order()
$this->assertTrue($model[$model->count() - 1]->isLastInOrder());
$this->assertFalse($model[$model->count() - 2]->isLastInOrder());
}

/** @test */
public function it_can_move_order_down_by_amount()
{
$moveBy = 6;
$oldOrder = 4;

$model = Dummy::find($oldOrder);
$others = Dummy::whereBetween('order_column', [$oldOrder + 1, $oldOrder + $moveBy])->get();

$this->assertEquals($model->order_column, $oldOrder);
foreach ($others as $index => $other) {
$this->assertEquals($other->order_column, $oldOrder + $index + 1);
}

$this->assertNotFalse($model->moveDownBy($moveBy));

$others = Dummy::whereKey($others)->get();

$this->assertEquals($model->order_column, $oldOrder + $moveBy);
foreach ($others as $index => $other) {
$this->assertEquals($other->order_column, $oldOrder + $index);
}
}

/** @test */
public function it_can_move_order_up_by_amount()
{
$moveBy = 6;
$oldOrder = 14;

$model = Dummy::find($oldOrder);
$others = Dummy::whereBetween('order_column', [$oldOrder - $moveBy, $oldOrder - 1])->ordered('desc')->get();

$this->assertEquals($model->order_column, $oldOrder);
foreach ($others as $index => $other) {
$this->assertEquals($other->order_column, $oldOrder - $index - 1);
}

$this->assertNotFalse($model->moveUpBy($moveBy));

$others = Dummy::whereKey($others)->ordered('desc')->get();

$this->assertEquals($model->order_column, $oldOrder - $moveBy);
foreach ($others as $index => $other) {
$this->assertEquals($other->order_column, $oldOrder - $index);
}
}
}

0 comments on commit 9b4899e

Please sign in to comment.