From e55becefe56b1606e67955d432eed8fbb425f2c6 Mon Sep 17 00:00:00 2001 From: AbdelrahmanBl <35730155+AbdelrahmanBl@users.noreply.github.com> Date: Mon, 11 Dec 2023 18:39:31 +0200 Subject: [PATCH] [FEAT] add withoutGlobalScopes to setNewOrder method (#167) * [FEAT] add withoutGlobalScopes to setNewOrder method * [FEAT] add withoutGlobalScopes to setNewOrder method * [FEAT] test it can set new order without global scope * Update README.md * Update README.md * [MOD] add modifyQuery with a callback instead of withoutGlobalScope for setting a new order * Update README.md * Update README.md * [FIX] fix missing modification of sqlite to mysql driver --------- Co-authored-by: Freek Van der Herten --- README.md | 14 ++++++++++++++ src/SortableTrait.php | 5 ++++- tests/DummyWithGlobalScope.php | 31 +++++++++++++++++++++++++++++++ tests/SortableTest.php | 16 ++++++++++++++++ tests/TestCase.php | 7 +++++++ 5 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 tests/DummyWithGlobalScope.php diff --git a/README.md b/README.md index ba3a521..3b0d140 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,20 @@ Optionally you can pass the starting order number as the second argument. MyModel::setNewOrder([3,1,2], 10); ``` +You can modify the query that will be executed by passing a closure as the fourth argument. + +```php +/** + * the record for model id 3 will have order_column value 11 + * the record for model id 1 will have order_column value 12 + * the record for model id 2 will have order_column value 13 + */ +MyModel::setNewOrder([3,1,2], 10, null, function($query) { + $query->withoutGlobalScope(new ActiveScope); +}); +``` + + To sort using a column other than the primary key, use the `setNewOrderByCustomColumn`-method. ```php diff --git a/src/SortableTrait.php b/src/SortableTrait.php index fc15668..f5cd4c3 100644 --- a/src/SortableTrait.php +++ b/src/SortableTrait.php @@ -40,7 +40,7 @@ public function scopeOrdered(Builder $query, string $direction = 'asc') return $query->orderBy($this->determineOrderColumnName(), $direction); } - public static function setNewOrder($ids, int $startOrder = 1, string $primaryKeyColumn = null): void + public static function setNewOrder($ids, int $startOrder = 1, string $primaryKeyColumn = null, callable $modifyQuery = null): void { if (! is_array($ids) && ! $ids instanceof ArrayAccess) { throw new InvalidArgumentException('You must pass an array or ArrayAccess object to setNewOrder'); @@ -56,6 +56,9 @@ public static function setNewOrder($ids, int $startOrder = 1, string $primaryKey foreach ($ids as $id) { static::withoutGlobalScope(SoftDeletingScope::class) + ->when(is_callable($modifyQuery), function($query) use ($modifyQuery) { + return $modifyQuery($query); + }) ->where($primaryKeyColumn, $id) ->update([$orderColumnName => $startOrder++]); } diff --git a/tests/DummyWithGlobalScope.php b/tests/DummyWithGlobalScope.php new file mode 100644 index 0000000..8a2561f --- /dev/null +++ b/tests/DummyWithGlobalScope.php @@ -0,0 +1,31 @@ +where('is_active', true); + }); + } +} diff --git a/tests/SortableTest.php b/tests/SortableTest.php index 159b71f..6ad83e1 100644 --- a/tests/SortableTest.php +++ b/tests/SortableTest.php @@ -78,6 +78,22 @@ public function it_can_set_a_new_order_by_custom_column_from_collection() } } + /** @test */ + public function it_can_set_new_order_without_global_scopes_models() + { + $this->setUpIsActiveFieldForGlobalScope(); + + $newOrder = Collection::make(Dummy::all()->pluck('id'))->shuffle()->toArray(); + + DummyWithGlobalScope::setNewOrder($newOrder, 1, null, function($query) { + $query->withoutGlobalScope('ActiveScope'); + }); + + foreach (Dummy::orderBy('order_column')->get() as $i => $dummy) { + $this->assertEquals($newOrder[$i], $dummy->id); + } + } + /** @test */ public function it_can_set_a_new_order_with_trashed_models() { diff --git a/tests/TestCase.php b/tests/TestCase.php index c9e7e8d..3c92594 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -62,4 +62,11 @@ protected function setUpSoftDeletes() $table->softDeletes(); }); } + + protected function setUpIsActiveFieldForGlobalScope() + { + $this->app['db']->connection()->getSchemaBuilder()->table('dummies', function (Blueprint $table) { + $table->boolean('is_active')->default(false); + }); + } }