From f325ea84c237b3b1e68394c701480160ef07e3d7 Mon Sep 17 00:00:00 2001 From: Morten Poul Jensen Date: Mon, 5 Aug 2019 09:49:07 +0200 Subject: [PATCH 1/3] ignore phpunit cache --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7579f74..50b321e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ vendor composer.lock +.phpunit.result.cache From f35c3aab97e658ae6d086ad2d2c0753b22d1694e Mon Sep 17 00:00:00 2001 From: Morten Poul Jensen Date: Mon, 5 Aug 2019 09:49:56 +0200 Subject: [PATCH 2/3] Reset pivot changes after dispatching events --- src/BelongsToMany.php | 6 ++++++ src/HasPivotEvents.php | 32 +++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/BelongsToMany.php b/src/BelongsToMany.php index 46f8f1d..a14bbe9 100644 --- a/src/BelongsToMany.php +++ b/src/BelongsToMany.php @@ -28,6 +28,8 @@ public function attach($id, array $attributes = [], $touch = true) $this->parent->firePivotAttachedEvent(); + $this->parent->resetPivotChanges(); + return $result; } @@ -60,6 +62,8 @@ public function detach($ids = null, $touch = true) $this->parent->firePivotDetachedEvent(); + $this->parent->resetPivotChanges(); + return $result; } @@ -85,6 +89,8 @@ public function updateExistingPivot($id, array $attributes, $touch = true) $this->parent->firePivotUpdatedEvent(); + $this->parent->resetPivotChanges(); + return $result; } } diff --git a/src/HasPivotEvents.php b/src/HasPivotEvents.php index c7c38a4..ccd8a86 100644 --- a/src/HasPivotEvents.php +++ b/src/HasPivotEvents.php @@ -2,6 +2,7 @@ namespace Signifly\PivotEvents; +use Illuminate\Support\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Builder; @@ -9,14 +10,14 @@ trait HasPivotEvents { protected $pivotChanges = []; - public function setPivotChanges(string $type, string $relation, array $ids = []) + public function setPivotChanges(string $type, string $relation, array $ids = []): void { collect($ids)->each(function ($attributes, $id) use ($type, $relation) { data_set($this->pivotChanges, "{$type}.{$relation}.{$id}", $attributes); }); } - public function getPivotChanges($type = null) + public function getPivotChanges($type = null): Collection { if ($type) { return collect(data_get($this->pivotChanges, $type)); @@ -25,11 +26,16 @@ public function getPivotChanges($type = null) return collect($this->pivotChanges); } - public function getPivotChangeIds($type, $relation) + public function getPivotChangeIds($type, $relation): Collection { return collect($this->getPivotChanges("{$type}.{$relation}"))->keys(); } + public function resetPivotChanges(): void + { + $this->pivotChanges = []; + } + public static function pivotAttaching($callback) { static::registerModelEvent('pivotAttaching', $callback); @@ -98,15 +104,12 @@ public function firePivotUpdatedEvent($halt = false) public function getObservableEvents() { return array_merge( + parent::getObservableEvents(), [ - 'retrieved', 'creating', 'created', 'updating', 'updated', - 'saving', 'saved', 'restoring', 'restored', - 'deleting', 'deleted', 'forceDeleted', 'pivotAttaching', 'pivotAttached', 'pivotDetaching', 'pivotDetached', 'pivotUpdating', 'pivotUpdated', - ], - $this->observables + ] ); } @@ -123,9 +126,16 @@ public function getObservableEvents() * @param string $relationName * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ - protected function newBelongsToMany(Builder $query, Model $parent, $table, $foreignPivotKey, $relatedPivotKey, - $parentKey, $relatedKey, $relationName = null) - { + protected function newBelongsToMany( + Builder $query, + Model $parent, + $table, + $foreignPivotKey, + $relatedPivotKey, + $parentKey, + $relatedKey, + $relationName = null + ) { return new BelongsToMany($query, $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName); } } From 2d5f0c1f9ee83760e8527549b53f47c94aee0399 Mon Sep 17 00:00:00 2001 From: Morten Poul Jensen Date: Mon, 5 Aug 2019 09:57:37 +0200 Subject: [PATCH 3/3] add test coverage for resetting pivot changes --- tests/PivotEventsTest.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/PivotEventsTest.php b/tests/PivotEventsTest.php index a231827..d0737b8 100644 --- a/tests/PivotEventsTest.php +++ b/tests/PivotEventsTest.php @@ -99,6 +99,31 @@ public function it_dispatches_pivot_update_events() Event::assertDispatched('eloquent.pivotUpdated: '.User::class); } + /** @test */ + public function it_resets_pivot_changes_after_an_event_has_been_dispatched() + { + $user = $this->createUser(); + $roleA = $this->createRole(['name' => 'role-a']); + $roleB = $this->createRole(['name' => 'role-b']); + + $calledTimes = 0; + + User::pivotAttached(function ($model) use (&$calledTimes) { + $this->assertCount(1, $model->getPivotChanges()); + $calledTimes++; + }); + + $user->roles()->attach($roleA->id); + $this->assertCount(0, $user->getPivotChanges()); + + $user->roles()->attach($roleB->id); + $this->assertCount(0, $user->getPivotChanges()); + + $this->assertCount(2, $user->roles); + + $this->assertEquals(2, $calledTimes); + } + protected function createRole(array $overwrites = []) { return Role::create(array_merge([