From 3598d74b130f297f41d0122c628ece106d356cab Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 28 Jul 2023 18:32:38 +0800 Subject: [PATCH 01/10] wip Signed-off-by: Mior Muhammad Zaki --- .../Database/Eloquent/Relations/MorphTo.php | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/Illuminate/Database/Eloquent/Relations/MorphTo.php b/src/Illuminate/Database/Eloquent/Relations/MorphTo.php index 4dd8059d072e..1dfe7d605d50 100644 --- a/src/Illuminate/Database/Eloquent/Relations/MorphTo.php +++ b/src/Illuminate/Database/Eloquent/Relations/MorphTo.php @@ -146,6 +146,10 @@ protected function getResultsByType($type) (array) ($this->morphableEagerLoadCounts[get_class($instance)] ?? []) ); + if ($callback = ($this->morphableConstraints['*'] ?? null)) { + $callback($query); + } + if ($callback = ($this->morphableConstraints[get_class($instance)] ?? null)) { $callback($query); } @@ -365,6 +369,48 @@ protected function replayMacros(Builder $query) return $query; } + /** + * Add the with-trashed to the query when available. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return void + */ + public function withTrashed() + { + $callback = fn ($query) => $query->hasMacro('withTrashed') ? $query->withTrashed() : $query; + + return $this->when(true, $callback) + ->constrain(['*' => $callback]); + } + + /** + * Add the without-trashed to the query when available. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return void + */ + public function withoutTrashed() + { + $callback = fn ($query) => $query->hasMacro('withoutTrashed') ? $query->withoutTrashed() : $query; + + return $this->when(true, $callback) + ->constrain(['*' => $callback]); + } + + /** + * Add the only-trashed to the query when available. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return void + */ + public function onlyTrashed() + { + $callback = fn ($query) => $query->hasMacro('onlyTrashed') ? $query->onlyTrashed() : $query; + + return $this->when(true, $callback) + ->constrain(['*' => $callback]); + } + /** * Handle dynamic method calls to the relationship. * From beeba4d95555581662d1e6741c43ea74633decbc Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 28 Jul 2023 20:56:52 +0800 Subject: [PATCH 02/10] wip Signed-off-by: Mior Muhammad Zaki --- .../Database/Eloquent/Relations/MorphTo.php | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Relations/MorphTo.php b/src/Illuminate/Database/Eloquent/Relations/MorphTo.php index 1dfe7d605d50..9e799a03ec70 100644 --- a/src/Illuminate/Database/Eloquent/Relations/MorphTo.php +++ b/src/Illuminate/Database/Eloquent/Relations/MorphTo.php @@ -372,43 +372,52 @@ protected function replayMacros(Builder $query) /** * Add the with-trashed to the query when available. * - * @param \Illuminate\Database\Eloquent\Builder $builder - * @return void + * @return $this */ public function withTrashed() { $callback = fn ($query) => $query->hasMacro('withTrashed') ? $query->withTrashed() : $query; - return $this->when(true, $callback) - ->constrain(['*' => $callback]); + $this->macroBuffer[] = [ + 'method' => 'when', + 'parameters' => [true, $callback], + ]; + + return $this->when(true, $callback); } /** * Add the without-trashed to the query when available. * - * @param \Illuminate\Database\Eloquent\Builder $builder - * @return void + * @return $this */ public function withoutTrashed() { $callback = fn ($query) => $query->hasMacro('withoutTrashed') ? $query->withoutTrashed() : $query; - return $this->when(true, $callback) - ->constrain(['*' => $callback]); + $this->macroBuffer[] = [ + 'method' => 'when', + 'parameters' => [true, $callback], + ]; + + return $this->when(true, $callback); } /** * Add the only-trashed to the query when available. * - * @param \Illuminate\Database\Eloquent\Builder $builder - * @return void + * @return $this */ public function onlyTrashed() { $callback = fn ($query) => $query->hasMacro('onlyTrashed') ? $query->onlyTrashed() : $query; - return $this->when(true, $callback) - ->constrain(['*' => $callback]); + $this->macroBuffer[] = [ + 'method' => 'when', + 'parameters' => [true, $callback], + ]; + + return $this->when(true, $callback); } /** From c57c06315b6b08baf2d80a190f7a943b54800c3d Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 28 Jul 2023 21:12:13 +0800 Subject: [PATCH 03/10] wip Signed-off-by: Mior Muhammad Zaki --- src/Illuminate/Database/Eloquent/Relations/MorphTo.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Relations/MorphTo.php b/src/Illuminate/Database/Eloquent/Relations/MorphTo.php index 9e799a03ec70..6b726ad7a417 100644 --- a/src/Illuminate/Database/Eloquent/Relations/MorphTo.php +++ b/src/Illuminate/Database/Eloquent/Relations/MorphTo.php @@ -146,10 +146,6 @@ protected function getResultsByType($type) (array) ($this->morphableEagerLoadCounts[get_class($instance)] ?? []) ); - if ($callback = ($this->morphableConstraints['*'] ?? null)) { - $callback($query); - } - if ($callback = ($this->morphableConstraints[get_class($instance)] ?? null)) { $callback($query); } From 0695411838d20ecb5d21819ce5ef737bb7efe7e6 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 28 Jul 2023 21:28:31 +0800 Subject: [PATCH 04/10] wip Signed-off-by: Mior Muhammad Zaki --- .../EloquentMorphEagerLoadingTest.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/Integration/Database/EloquentMorphEagerLoadingTest.php b/tests/Integration/Database/EloquentMorphEagerLoadingTest.php index 5a512d7a7069..19f7b9d7c031 100644 --- a/tests/Integration/Database/EloquentMorphEagerLoadingTest.php +++ b/tests/Integration/Database/EloquentMorphEagerLoadingTest.php @@ -39,6 +39,7 @@ protected function defineDatabaseMigrationsAfterDatabaseRefreshed() (new Comment)->commentable()->associate($post)->save(); (new Comment)->commentable()->associate($video)->save(); + (new Comment)->commentable()->associate($user)->save(); } public function testWithMorphLoading() @@ -52,6 +53,7 @@ public function testWithMorphLoading() $this->assertTrue($comments[0]->relationLoaded('commentable')); $this->assertTrue($comments[0]->commentable->relationLoaded('user')); $this->assertTrue($comments[1]->relationLoaded('commentable')); + $this->assertTrue($comments[2]->relationLoaded('commentable')); } public function testWithMorphLoadingWithSingleRelation() @@ -65,6 +67,18 @@ public function testWithMorphLoadingWithSingleRelation() $this->assertTrue($comments[0]->relationLoaded('commentable')); $this->assertTrue($comments[0]->commentable->relationLoaded('user')); } + + public function testMorphLoadingMixedWithTrashedRelations() + { + $comments = Comment::query() + ->with('commentable_with_trashed') + ->get(); + + $this->assertTrue($comments[0]->relationLoaded('commentable_with_trashed')); + $this->assertNull($comments[0]->getRelation('commentable_with_trashed')); + $this->assertTrue($comments[1]->relationLoaded('commentable_with_trashed')); + $this->assertTrue($comments[2]->relationLoaded('commentable_with_trashed')); + } } class Comment extends Model @@ -75,6 +89,11 @@ public function commentable() { return $this->morphTo(); } + + public function commentable_with_trashed() + { + return $this->commentable()->withTrashed(); + } } class Post extends Model From c1cac05753f2102a93e59747f318874509cb6b8e Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 28 Jul 2023 21:33:20 +0800 Subject: [PATCH 05/10] wip Signed-off-by: Mior Muhammad Zaki --- tests/Integration/Database/EloquentMorphEagerLoadingTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/Integration/Database/EloquentMorphEagerLoadingTest.php b/tests/Integration/Database/EloquentMorphEagerLoadingTest.php index 19f7b9d7c031..5345ccbef040 100644 --- a/tests/Integration/Database/EloquentMorphEagerLoadingTest.php +++ b/tests/Integration/Database/EloquentMorphEagerLoadingTest.php @@ -39,7 +39,6 @@ protected function defineDatabaseMigrationsAfterDatabaseRefreshed() (new Comment)->commentable()->associate($post)->save(); (new Comment)->commentable()->associate($video)->save(); - (new Comment)->commentable()->associate($user)->save(); } public function testWithMorphLoading() @@ -53,7 +52,6 @@ public function testWithMorphLoading() $this->assertTrue($comments[0]->relationLoaded('commentable')); $this->assertTrue($comments[0]->commentable->relationLoaded('user')); $this->assertTrue($comments[1]->relationLoaded('commentable')); - $this->assertTrue($comments[2]->relationLoaded('commentable')); } public function testWithMorphLoadingWithSingleRelation() @@ -77,7 +75,6 @@ public function testMorphLoadingMixedWithTrashedRelations() $this->assertTrue($comments[0]->relationLoaded('commentable_with_trashed')); $this->assertNull($comments[0]->getRelation('commentable_with_trashed')); $this->assertTrue($comments[1]->relationLoaded('commentable_with_trashed')); - $this->assertTrue($comments[2]->relationLoaded('commentable_with_trashed')); } } From 654f622e6e1a862b57b57c9210a76a56cb03ed7b Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 28 Jul 2023 21:44:59 +0800 Subject: [PATCH 06/10] wip Signed-off-by: Mior Muhammad Zaki --- .../Database/EloquentMorphEagerLoadingTest.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/Integration/Database/EloquentMorphEagerLoadingTest.php b/tests/Integration/Database/EloquentMorphEagerLoadingTest.php index 5345ccbef040..79ed8b52760a 100644 --- a/tests/Integration/Database/EloquentMorphEagerLoadingTest.php +++ b/tests/Integration/Database/EloquentMorphEagerLoadingTest.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\MorphTo; +use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; use Illuminate\Tests\Integration\Database\DatabaseTestCase; @@ -14,6 +15,7 @@ protected function defineDatabaseMigrationsAfterDatabaseRefreshed() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); + $table->softDeletes(); }); Schema::create('posts', function (Blueprint $table) { @@ -32,6 +34,7 @@ protected function defineDatabaseMigrationsAfterDatabaseRefreshed() }); $user = User::create(); + $user2 = User::forceCreate(['deleted_at' => now()]); $post = tap((new Post)->user()->associate($user))->save(); @@ -39,6 +42,7 @@ protected function defineDatabaseMigrationsAfterDatabaseRefreshed() (new Comment)->commentable()->associate($post)->save(); (new Comment)->commentable()->associate($video)->save(); + (new Comment)->commentable()->associate($user2)->save(); } public function testWithMorphLoading() @@ -49,9 +53,13 @@ public function testWithMorphLoading() }]) ->get(); + $this->assertCount(3, $comments); + $this->assertTrue($comments[0]->relationLoaded('commentable')); $this->assertTrue($comments[0]->commentable->relationLoaded('user')); $this->assertTrue($comments[1]->relationLoaded('commentable')); + $this->assertTrue($comments[2]->relationLoaded('commentable')); + $this->assertNull($comments[2]->commentable); } public function testWithMorphLoadingWithSingleRelation() @@ -72,9 +80,13 @@ public function testMorphLoadingMixedWithTrashedRelations() ->with('commentable_with_trashed') ->get(); + $this->assertCount(3, $comments); + $this->assertTrue($comments[0]->relationLoaded('commentable_with_trashed')); $this->assertNull($comments[0]->getRelation('commentable_with_trashed')); $this->assertTrue($comments[1]->relationLoaded('commentable_with_trashed')); + $this->assertTrue($comments[2]->relationLoaded('commentable_with_trashed')); + $this->assertNull($comments[2]->getRelation('commentable_with_trashed')); } } @@ -89,7 +101,7 @@ public function commentable() public function commentable_with_trashed() { - return $this->commentable()->withTrashed(); + return $this->morphTo('commentable')->withTrashed(); } } @@ -106,6 +118,8 @@ public function user() class User extends Model { + use SoftDeletes; + public $timestamps = false; } From 9d3bf4797d44d645d2310b82e1343738d56518de Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 28 Jul 2023 22:02:11 +0800 Subject: [PATCH 07/10] wip Signed-off-by: Mior Muhammad Zaki --- .../EloquentMorphEagerLoadingTest.php | 49 ++++++++++++------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/tests/Integration/Database/EloquentMorphEagerLoadingTest.php b/tests/Integration/Database/EloquentMorphEagerLoadingTest.php index 79ed8b52760a..78243dda1eb8 100644 --- a/tests/Integration/Database/EloquentMorphEagerLoadingTest.php +++ b/tests/Integration/Database/EloquentMorphEagerLoadingTest.php @@ -27,10 +27,18 @@ protected function defineDatabaseMigrationsAfterDatabaseRefreshed() $table->increments('video_id'); }); + Schema::create('actions', function (Blueprint $table) { + $table->increments('id'); + $table->string('target_type'); + $table->integer('target_id'); + }); + Schema::create('comments', function (Blueprint $table) { $table->increments('id'); $table->string('commentable_type'); $table->integer('commentable_id'); + $table->string('target_type')->nullable(); + $table->integer('target_id')->nullable(); }); $user = User::create(); @@ -42,7 +50,9 @@ protected function defineDatabaseMigrationsAfterDatabaseRefreshed() (new Comment)->commentable()->associate($post)->save(); (new Comment)->commentable()->associate($video)->save(); - (new Comment)->commentable()->associate($user2)->save(); + + (new Action)->target()->associate($video)->save(); + (new Action)->target()->associate($user2)->save(); } public function testWithMorphLoading() @@ -53,13 +63,13 @@ public function testWithMorphLoading() }]) ->get(); - $this->assertCount(3, $comments); + $this->assertCount(2, $comments); $this->assertTrue($comments[0]->relationLoaded('commentable')); + $this->assertInstanceOf(Post::class, $comments[0]->getRelation('commentable')); $this->assertTrue($comments[0]->commentable->relationLoaded('user')); $this->assertTrue($comments[1]->relationLoaded('commentable')); - $this->assertTrue($comments[2]->relationLoaded('commentable')); - $this->assertNull($comments[2]->commentable); + $this->assertInstanceOf(Video::class, $comments[1]->getRelation('commentable')); } public function testWithMorphLoadingWithSingleRelation() @@ -76,32 +86,37 @@ public function testWithMorphLoadingWithSingleRelation() public function testMorphLoadingMixedWithTrashedRelations() { - $comments = Comment::query() - ->with('commentable_with_trashed') + $action = Action::query() + ->with('target') ->get(); - $this->assertCount(3, $comments); + $this->assertCount(2, $action); - $this->assertTrue($comments[0]->relationLoaded('commentable_with_trashed')); - $this->assertNull($comments[0]->getRelation('commentable_with_trashed')); - $this->assertTrue($comments[1]->relationLoaded('commentable_with_trashed')); - $this->assertTrue($comments[2]->relationLoaded('commentable_with_trashed')); - $this->assertNull($comments[2]->getRelation('commentable_with_trashed')); + $this->assertTrue($action[0]->relationLoaded('target')); + $this->assertInstanceOf(Video::class, $action[0]->getRelation('target')); + $this->assertTrue($action[1]->relationLoaded('target')); + $this->assertInstanceOf(User::class, $action[1]->getRelation('target')); } } -class Comment extends Model + +class Action extends Model { public $timestamps = false; - public function commentable() + public function target() { - return $this->morphTo(); + return $this->morphTo()->withTrashed(); } +} + +class Comment extends Model +{ + public $timestamps = false; - public function commentable_with_trashed() + public function commentable() { - return $this->morphTo('commentable')->withTrashed(); + return $this->morphTo(); } } From c1eea806896e42a4b401a4ca7700e59b88a856ba Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 28 Jul 2023 22:03:37 +0800 Subject: [PATCH 08/10] wip Signed-off-by: Mior Muhammad Zaki --- tests/Integration/Database/EloquentMorphEagerLoadingTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Integration/Database/EloquentMorphEagerLoadingTest.php b/tests/Integration/Database/EloquentMorphEagerLoadingTest.php index 78243dda1eb8..368adc433566 100644 --- a/tests/Integration/Database/EloquentMorphEagerLoadingTest.php +++ b/tests/Integration/Database/EloquentMorphEagerLoadingTest.php @@ -99,7 +99,6 @@ public function testMorphLoadingMixedWithTrashedRelations() } } - class Action extends Model { public $timestamps = false; From 6f2a01ada21e7386063fba1919db31c157035fcd Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Sun, 30 Jul 2023 08:11:52 +0800 Subject: [PATCH 09/10] Update tests/Integration/Database/EloquentMorphEagerLoadingTest.php --- tests/Integration/Database/EloquentMorphEagerLoadingTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/Integration/Database/EloquentMorphEagerLoadingTest.php b/tests/Integration/Database/EloquentMorphEagerLoadingTest.php index 368adc433566..058f981b4b1a 100644 --- a/tests/Integration/Database/EloquentMorphEagerLoadingTest.php +++ b/tests/Integration/Database/EloquentMorphEagerLoadingTest.php @@ -37,8 +37,6 @@ protected function defineDatabaseMigrationsAfterDatabaseRefreshed() $table->increments('id'); $table->string('commentable_type'); $table->integer('commentable_id'); - $table->string('target_type')->nullable(); - $table->integer('target_id')->nullable(); }); $user = User::create(); From 4bca06699a2d221da67c4ae986e686df2d2cbdf7 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Tue, 15 Aug 2023 13:56:15 -0500 Subject: [PATCH 10/10] formatting --- .../Database/Eloquent/Relations/MorphTo.php | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Relations/MorphTo.php b/src/Illuminate/Database/Eloquent/Relations/MorphTo.php index 6b726ad7a417..15de0bfe56dd 100644 --- a/src/Illuminate/Database/Eloquent/Relations/MorphTo.php +++ b/src/Illuminate/Database/Eloquent/Relations/MorphTo.php @@ -351,22 +351,7 @@ public function constrain(array $callbacks) } /** - * Replay stored macro calls on the actual related instance. - * - * @param \Illuminate\Database\Eloquent\Builder $query - * @return \Illuminate\Database\Eloquent\Builder - */ - protected function replayMacros(Builder $query) - { - foreach ($this->macroBuffer as $macro) { - $query->{$macro['method']}(...$macro['parameters']); - } - - return $query; - } - - /** - * Add the with-trashed to the query when available. + * Indicate that soft deleted models should be included in the results. * * @return $this */ @@ -383,7 +368,7 @@ public function withTrashed() } /** - * Add the without-trashed to the query when available. + * Indicate that soft deleted models should not be included in the results. * * @return $this */ @@ -400,7 +385,7 @@ public function withoutTrashed() } /** - * Add the only-trashed to the query when available. + * Indicate that only soft deleted models should be included in the results. * * @return $this */ @@ -416,6 +401,21 @@ public function onlyTrashed() return $this->when(true, $callback); } + /** + * Replay stored macro calls on the actual related instance. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @return \Illuminate\Database\Eloquent\Builder + */ + protected function replayMacros(Builder $query) + { + foreach ($this->macroBuffer as $macro) { + $query->{$macro['method']}(...$macro['parameters']); + } + + return $query; + } + /** * Handle dynamic method calls to the relationship. *