From 2391e677d5519ebf90abd94293edc0d3a334132e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 17:56:12 +0000 Subject: [PATCH 1/4] Bump dependabot/fetch-metadata from 1.6.0 to 2.1.0 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.6.0 to 2.1.0. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.6.0...v2.1.0) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/dependabot-auto-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index 60183c5..c09678f 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -13,7 +13,7 @@ jobs: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v1.6.0 + uses: dependabot/fetch-metadata@v2.1.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" compat-lookup: true From 6c49c89a7f68563e4a0a4f0048537a9660954168 Mon Sep 17 00:00:00 2001 From: Chris Page Date: Fri, 31 May 2024 16:59:38 +0100 Subject: [PATCH 2/4] Dispatch event on sortable update --- src/EloquentModelSortedEvent.php | 13 +++++++++++++ src/SortableTrait.php | 2 ++ tests/SortableTest.php | 9 +++++++++ 3 files changed, 24 insertions(+) create mode 100644 src/EloquentModelSortedEvent.php diff --git a/src/EloquentModelSortedEvent.php b/src/EloquentModelSortedEvent.php new file mode 100644 index 0000000..b3cbb0b --- /dev/null +++ b/src/EloquentModelSortedEvent.php @@ -0,0 +1,13 @@ +model = $model; + } +} diff --git a/src/SortableTrait.php b/src/SortableTrait.php index b3a6cd3..ddc780f 100644 --- a/src/SortableTrait.php +++ b/src/SortableTrait.php @@ -67,6 +67,8 @@ public static function setNewOrder($ids, int $startOrder = 1, string $primaryKey ->update([$orderColumnName => $startOrder++]); } + event(new EloquentModelSortedEvent(static::class)); + if (config('eloquent-sortable.ignore_timestamps', false)) { static::$ignoreTimestampsOn = array_values(array_diff(static::$ignoreTimestampsOn, [static::class])); } diff --git a/tests/SortableTest.php b/tests/SortableTest.php index 4b7248a..d0a6d6e 100644 --- a/tests/SortableTest.php +++ b/tests/SortableTest.php @@ -3,6 +3,8 @@ namespace Spatie\EloquentSortable\Test; use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Event; +use Spatie\EloquentSortable\EloquentModelSortedEvent; class SortableTest extends TestCase { @@ -33,6 +35,9 @@ public function it_can_get_the_highest_order_number_with_trashed_models() /** @test */ public function it_can_set_a_new_order() { + + Event::fake(EloquentModelSortedEvent::class); + $newOrder = Collection::make(Dummy::all()->pluck('id'))->shuffle()->toArray(); Dummy::setNewOrder($newOrder); @@ -40,6 +45,10 @@ public function it_can_set_a_new_order() foreach (Dummy::orderBy('order_column')->get() as $i => $dummy) { $this->assertEquals($newOrder[$i], $dummy->id); } + + Event::assertDispatched(EloquentModelSortedEvent::class, function (EloquentModelSortedEvent $event) { + return $event->model === Dummy::class; + }); } /** @test */ From facbeb94d82812a9b107ba9d2d9e1a0ec2796c4e Mon Sep 17 00:00:00 2001 From: Chris Page Date: Fri, 31 May 2024 17:04:01 +0100 Subject: [PATCH 3/4] Changed to Event::dispatch() Added convenience helper to event --- src/EloquentModelSortedEvent.php | 11 +++++++++++ src/SortableTrait.php | 25 ++++++++++++++++--------- tests/SortableTest.php | 2 +- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/EloquentModelSortedEvent.php b/src/EloquentModelSortedEvent.php index b3cbb0b..3c78bec 100644 --- a/src/EloquentModelSortedEvent.php +++ b/src/EloquentModelSortedEvent.php @@ -2,6 +2,8 @@ namespace Spatie\EloquentSortable; +use Illuminate\Database\Eloquent\Model; + class EloquentModelSortedEvent { public string $model; @@ -10,4 +12,13 @@ public function __construct(string $model) { $this->model = $model; } + + public function isFor(Model|string $model): bool + { + if (is_string($model)) { + return $model === $this->model; + } + + return get_class($model) === $this->model; + } } diff --git a/src/SortableTrait.php b/src/SortableTrait.php index ddc780f..40ce734 100644 --- a/src/SortableTrait.php +++ b/src/SortableTrait.php @@ -5,6 +5,7 @@ use ArrayAccess; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; +use Illuminate\Support\Facades\Event; use InvalidArgumentException; trait SortableTrait @@ -27,12 +28,12 @@ public function setHighestOrderNumber(): void public function getHighestOrderNumber(): int { - return (int) $this->buildSortQuery()->max($this->determineOrderColumnName()); + return (int)$this->buildSortQuery()->max($this->determineOrderColumnName()); } public function getLowestOrderNumber(): int { - return (int) $this->buildSortQuery()->min($this->determineOrderColumnName()); + return (int)$this->buildSortQuery()->min($this->determineOrderColumnName()); } public function scopeOrdered(Builder $query, string $direction = 'asc') @@ -40,9 +41,13 @@ 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, callable $modifyQuery = null): void - { - if (! is_array($ids) && ! $ids instanceof ArrayAccess) { + 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'); } @@ -67,7 +72,7 @@ public static function setNewOrder($ids, int $startOrder = 1, string $primaryKey ->update([$orderColumnName => $startOrder++]); } - event(new EloquentModelSortedEvent(static::class)); + Event::dispatch(new EloquentModelSortedEvent(static::class)); if (config('eloquent-sortable.ignore_timestamps', false)) { static::$ignoreTimestampsOn = array_values(array_diff(static::$ignoreTimestampsOn, [static::class])); @@ -101,7 +106,7 @@ public function moveOrderDown(): static ->where($orderColumnName, '>', $this->$orderColumnName) ->first(); - if (! $swapWithModel) { + if (!$swapWithModel) { return $this; } @@ -117,7 +122,7 @@ public function moveOrderUp(): static ->where($orderColumnName, '<', $this->$orderColumnName) ->first(); - if (! $swapWithModel) { + if (!$swapWithModel) { return $this; } @@ -159,7 +164,9 @@ public function moveToStart(): static $this->$orderColumnName = $firstModel->$orderColumnName; $this->save(); - $this->buildSortQuery()->where($this->getQualifiedKeyName(), '!=', $this->getKey())->increment($orderColumnName); + $this->buildSortQuery()->where($this->getQualifiedKeyName(), '!=', $this->getKey())->increment( + $orderColumnName + ); return $this; } diff --git a/tests/SortableTest.php b/tests/SortableTest.php index d0a6d6e..11ad2ff 100644 --- a/tests/SortableTest.php +++ b/tests/SortableTest.php @@ -47,7 +47,7 @@ public function it_can_set_a_new_order() } Event::assertDispatched(EloquentModelSortedEvent::class, function (EloquentModelSortedEvent $event) { - return $event->model === Dummy::class; + return $event->isFor(Dummy::class); }); } From cab118935fe41ffe2cc1a0daa17e961cb2adcec0 Mon Sep 17 00:00:00 2001 From: Chris Page Date: Tue, 4 Jun 2024 11:01:29 +0100 Subject: [PATCH 4/4] Updated README docs --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index 8d0692e..3e5078c 100644 --- a/README.md +++ b/README.md @@ -225,6 +225,29 @@ public function buildSortQuery() ``` This will restrict the calculations to fields value of the model instance. +### Dispatched events + +Once a sort has been completed, an event (`Spatie\EloquentSortable\EloquentModelSortedEvent`) is dispatched that you +can listen for. This can be useful for running post-sorting logic such as clearing caches or other actions that +need to be taken after a sort. + +The event has an `isFor` helper which allows you to conveniently check the Eloquent class that has been sorted. + +Below is an example of how you can listen for this event: + +```php +use Spatie\EloquentSortable\EloquentModelSortedEvent as SortEvent; + +class SortingListener +{ + public function handle(SortEvent $event): void { + if ($event->isFor(MyClass::class)) { + // ToDo: flush our cache + } + } +} +``` + ## Tests The package contains some integration/smoke tests, set up with Orchestra. The tests can be run via phpunit.