From f6bf6347459c0519d082db9fe774861087d51199 Mon Sep 17 00:00:00 2001 From: AbdelrahmanBl Date: Wed, 22 Nov 2023 16:49:46 +0200 Subject: [PATCH 1/9] [FEAT] add withoutGlobalScopes to setNewOrder method --- src/SortableTrait.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/SortableTrait.php b/src/SortableTrait.php index fc15668..af6950b 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, array $withoutGlobalScopes = []): 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($withoutGlobalScopes, function($query, $withoutGlobalScopes) { + $query->withoutGlobalScopes($withoutGlobalScopes); + }) ->where($primaryKeyColumn, $id) ->update([$orderColumnName => $startOrder++]); } From 027cf377aaece91976331f12606aaa83f0fe6435 Mon Sep 17 00:00:00 2001 From: AbdelrahmanBl Date: Wed, 22 Nov 2023 16:54:46 +0200 Subject: [PATCH 2/9] [FEAT] add withoutGlobalScopes to setNewOrder method --- src/SortableTrait.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/SortableTrait.php b/src/SortableTrait.php index af6950b..1249e8c 100644 --- a/src/SortableTrait.php +++ b/src/SortableTrait.php @@ -56,9 +56,7 @@ public static function setNewOrder($ids, int $startOrder = 1, string $primaryKey foreach ($ids as $id) { static::withoutGlobalScope(SoftDeletingScope::class) - ->when($withoutGlobalScopes, function($query, $withoutGlobalScopes) { - $query->withoutGlobalScopes($withoutGlobalScopes); - }) + ->withoutGlobalScopes($withoutGlobalScopes) ->where($primaryKeyColumn, $id) ->update([$orderColumnName => $startOrder++]); } From 2117e30ecc3406849b21a34928efb2a037f96ef9 Mon Sep 17 00:00:00 2001 From: AbdelrahmanBl Date: Thu, 7 Dec 2023 12:18:42 +0200 Subject: [PATCH 3/9] [FEAT] test it can set new order without global scope --- tests/DummyWithGlobalScope.php | 31 +++++++++++++++++++++++++++++++ tests/SortableTest.php | 14 ++++++++++++++ tests/TestCase.php | 7 +++++++ 3 files changed, 52 insertions(+) create mode 100644 tests/DummyWithGlobalScope.php 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..c790bc9 100644 --- a/tests/SortableTest.php +++ b/tests/SortableTest.php @@ -78,6 +78,20 @@ 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, ['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); + }); + } } From f94821ab9ba10d2fae7b56dc0f74c4bc7ad0ba58 Mon Sep 17 00:00:00 2001 From: AbdelrahmanBl <35730155+AbdelrahmanBl@users.noreply.github.com> Date: Thu, 7 Dec 2023 12:27:08 +0200 Subject: [PATCH 4/9] Update README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index ba3a521..4e8254b 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,19 @@ Optionally you can pass the starting order number as the second argument. MyModel::setNewOrder([3,1,2], 10); ``` +You can set a new order without global scopes. + +```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 + */ +$yourGlobalScopes = [new ActiveScope, new DefaultScope]; +MyModel::setNewOrder([3,1,2], 10, null, $yourGlobalScopes); +``` + + To sort using a column other than the primary key, use the `setNewOrderByCustomColumn`-method. ```php From 58ff9526de445c67a59df31eb1c2572d9ae08788 Mon Sep 17 00:00:00 2001 From: AbdelrahmanBl <35730155+AbdelrahmanBl@users.noreply.github.com> Date: Thu, 7 Dec 2023 12:28:02 +0200 Subject: [PATCH 5/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4e8254b..8dbff01 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ Optionally you can pass the starting order number as the second argument. MyModel::setNewOrder([3,1,2], 10); ``` -You can set a new order without global scopes. +You can set a new order without global scopes as the fourth argument. ```php /** From 179038413543b06c1688350be41d77b8cbf4c72d Mon Sep 17 00:00:00 2001 From: AbdelrahmanBl Date: Mon, 11 Dec 2023 17:34:42 +0200 Subject: [PATCH 6/9] [MOD] add modifyQuery with a callback instead of withoutGlobalScope for setting a new order --- src/SortableTrait.php | 6 ++++-- tests/SortableTest.php | 4 +++- tests/TestCase.php | 5 ++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/SortableTrait.php b/src/SortableTrait.php index 1249e8c..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, array $withoutGlobalScopes = []): 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,7 +56,9 @@ public static function setNewOrder($ids, int $startOrder = 1, string $primaryKey foreach ($ids as $id) { static::withoutGlobalScope(SoftDeletingScope::class) - ->withoutGlobalScopes($withoutGlobalScopes) + ->when(is_callable($modifyQuery), function($query) use ($modifyQuery) { + return $modifyQuery($query); + }) ->where($primaryKeyColumn, $id) ->update([$orderColumnName => $startOrder++]); } diff --git a/tests/SortableTest.php b/tests/SortableTest.php index c790bc9..6ad83e1 100644 --- a/tests/SortableTest.php +++ b/tests/SortableTest.php @@ -85,7 +85,9 @@ public function it_can_set_new_order_without_global_scopes_models() $newOrder = Collection::make(Dummy::all()->pluck('id'))->shuffle()->toArray(); - DummyWithGlobalScope::setNewOrder($newOrder, 1, null, ['ActiveScope']); + 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); diff --git a/tests/TestCase.php b/tests/TestCase.php index 3c92594..203f6d1 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -3,6 +3,7 @@ namespace Spatie\EloquentSortable\Test; use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Schema; use Orchestra\Testbench\TestCase as Orchestra; abstract class TestCase extends Orchestra @@ -31,7 +32,7 @@ protected function getPackageProviders($app) */ protected function getEnvironmentSetUp($app) { - $app['config']->set('database.default', 'sqlite'); + $app['config']->set('database.default', 'mysql'); $app['config']->set('database.connections.sqlite', [ 'driver' => 'sqlite', 'database' => ':memory:', @@ -41,6 +42,8 @@ protected function getEnvironmentSetUp($app) protected function setUpDatabase() { + Schema::dropIfExists('dummies'); + $this->app['db']->connection()->getSchemaBuilder()->create('dummies', function (Blueprint $table) { $table->increments('id'); $table->string('name'); From 10eca38f0238280acfc60d8bd19da15aed5f2da6 Mon Sep 17 00:00:00 2001 From: AbdelrahmanBl <35730155+AbdelrahmanBl@users.noreply.github.com> Date: Mon, 11 Dec 2023 17:37:46 +0200 Subject: [PATCH 7/9] Update README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8dbff01..cca8172 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ Optionally you can pass the starting order number as the second argument. MyModel::setNewOrder([3,1,2], 10); ``` -You can set a new order without global scopes as the fourth argument. +You can set a new order with a closure as the fourth argument. ```php /** @@ -142,8 +142,9 @@ You can set a new order without global scopes as the fourth argument. * the record for model id 1 will have order_column value 12 * the record for model id 2 will have order_column value 13 */ -$yourGlobalScopes = [new ActiveScope, new DefaultScope]; -MyModel::setNewOrder([3,1,2], 10, null, $yourGlobalScopes); +MyModel::setNewOrder([3,1,2], 10, null, function($query) { + $query->withoutGlobalScope(new ActiveScope); +}); ``` From 61a5421b94050aa238cdf299dc71ee8aa8cb4696 Mon Sep 17 00:00:00 2001 From: Freek Van der Herten Date: Mon, 11 Dec 2023 16:40:05 +0100 Subject: [PATCH 8/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cca8172..3b0d140 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ Optionally you can pass the starting order number as the second argument. MyModel::setNewOrder([3,1,2], 10); ``` -You can set a new order with a closure as the fourth argument. +You can modify the query that will be executed by passing a closure as the fourth argument. ```php /** From c11516d5c84bd729d96567369de0851a7a1bd81f Mon Sep 17 00:00:00 2001 From: AbdelrahmanBl Date: Mon, 11 Dec 2023 17:53:00 +0200 Subject: [PATCH 9/9] [FIX] fix missing modification of sqlite to mysql driver --- tests/TestCase.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/TestCase.php b/tests/TestCase.php index 203f6d1..3c92594 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -3,7 +3,6 @@ namespace Spatie\EloquentSortable\Test; use Illuminate\Database\Schema\Blueprint; -use Illuminate\Support\Facades\Schema; use Orchestra\Testbench\TestCase as Orchestra; abstract class TestCase extends Orchestra @@ -32,7 +31,7 @@ protected function getPackageProviders($app) */ protected function getEnvironmentSetUp($app) { - $app['config']->set('database.default', 'mysql'); + $app['config']->set('database.default', 'sqlite'); $app['config']->set('database.connections.sqlite', [ 'driver' => 'sqlite', 'database' => ':memory:', @@ -42,8 +41,6 @@ protected function getEnvironmentSetUp($app) protected function setUpDatabase() { - Schema::dropIfExists('dummies'); - $this->app['db']->connection()->getSchemaBuilder()->create('dummies', function (Blueprint $table) { $table->increments('id'); $table->string('name');