From 54c9a859b66bab3b5425e5845e8e3daa839d7fa6 Mon Sep 17 00:00:00 2001 From: Mohammad Mortazavi Date: Mon, 6 Nov 2023 16:09:01 +0330 Subject: [PATCH 01/13] KeyName as default value for ownerKey; --- src/Eloquent/HybridRelations.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Eloquent/HybridRelations.php b/src/Eloquent/HybridRelations.php index 9e11605a3..9de518200 100644 --- a/src/Eloquent/HybridRelations.php +++ b/src/Eloquent/HybridRelations.php @@ -212,6 +212,10 @@ public function morphTo($name = null, $type = null, $id = null, $ownerKey = null [$type, $id] = $this->getMorphs(Str::snake($name), $type, $id); + if ($ownerKey === null){ + $ownerKey = $this->getKeyName(); + } + // If the type value is null it is probably safe to assume we're eager loading // the relationship. When that is the case we will pass in a dummy query as // there are multiple types in the morph and we can't use single queries. From 1a5fd7aba3185fbe4f3da479c7ed31cc5de3704d Mon Sep 17 00:00:00 2001 From: Mohammad Mortazavi Date: Mon, 6 Nov 2023 16:09:28 +0330 Subject: [PATCH 02/13] Add test for inverse MorphTo; --- tests/RelationsTest.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/RelationsTest.php b/tests/RelationsTest.php index 6b2e2539f..905f02a06 100644 --- a/tests/RelationsTest.php +++ b/tests/RelationsTest.php @@ -429,6 +429,7 @@ public function testBelongsToManyCustom(): void $this->assertEquals($user->_id, $group->users()->first()->_id); } + /** @group hans */ public function testMorph(): void { $user = User::create(['name' => 'John Doe']); @@ -470,6 +471,14 @@ public function testMorph(): void $relations = $photos[1]->getRelations(); $this->assertArrayHasKey('hasImage', $relations); $this->assertInstanceOf(Client::class, $photos[1]->hasImage); + + // inverse + $photo = Photo::query()->create(['url' => 'http://graph.facebook.com/jane.doe/picture']); + $client = Client::create(['name' => 'Hans Thomas']); + $photo->hasImage()->associate($client)->save(); + + $this->assertCount(1, $photo->hasImage()->get()); + $this->assertEquals($client->_id, $photo->hasImage->_id); } public function testHasManyHas(): void From c7287791bb3beb993033d2b1b5e8b3a70f0f673e Mon Sep 17 00:00:00 2001 From: Mohammad Mortazavi Date: Mon, 6 Nov 2023 16:16:13 +0330 Subject: [PATCH 03/13] Add test for inverse MorphTo with custom ownerKey; --- tests/Models/Photo.php | 5 +++++ tests/RelationsTest.php | 12 +++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/Models/Photo.php b/tests/Models/Photo.php index dbb92b0ff..b7f7d6b26 100644 --- a/tests/Models/Photo.php +++ b/tests/Models/Photo.php @@ -17,4 +17,9 @@ public function hasImage(): MorphTo { return $this->morphTo(); } + + public function hasImageWithCustomOwnerKey(): MorphTo + { + return $this->morphTo(ownerKey: 'cphoto_id'); + } } diff --git a/tests/RelationsTest.php b/tests/RelationsTest.php index 905f02a06..36f636fb2 100644 --- a/tests/RelationsTest.php +++ b/tests/RelationsTest.php @@ -473,11 +473,21 @@ public function testMorph(): void $this->assertInstanceOf(Client::class, $photos[1]->hasImage); // inverse - $photo = Photo::query()->create(['url' => 'http://graph.facebook.com/jane.doe/picture']); + $photo = Photo::query()->create(['url' => 'https://graph.facebook.com/hans.thomas/picture']); $client = Client::create(['name' => 'Hans Thomas']); $photo->hasImage()->associate($client)->save(); $this->assertCount(1, $photo->hasImage()->get()); + $this->assertInstanceOf(Client::class, $photo->hasImage); + $this->assertEquals($client->_id, $photo->hasImage->_id); + + // inverse with custom ownerKey + $photo = Photo::query()->create(['cphoto_id'=>(string)(new ObjectId()), 'url' => 'https://graph.facebook.com/young.gerald/picture']); + $client = Client::create(['name' => 'Young Gerald']); + $photo->hasImage()->associate($client)->save(); + + $this->assertCount(1, $photo->hasImage()->get()); + $this->assertInstanceOf(Client::class, $photo->hasImage); $this->assertEquals($client->_id, $photo->hasImage->_id); } From 474f1b1c286eed182f9eab5587198ecc0615414a Mon Sep 17 00:00:00 2001 From: Mohammad Mortazavi Date: Mon, 6 Nov 2023 16:17:11 +0330 Subject: [PATCH 04/13] Remove comment; --- tests/RelationsTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/RelationsTest.php b/tests/RelationsTest.php index 36f636fb2..0114c6cc1 100644 --- a/tests/RelationsTest.php +++ b/tests/RelationsTest.php @@ -429,7 +429,6 @@ public function testBelongsToManyCustom(): void $this->assertEquals($user->_id, $group->users()->first()->_id); } - /** @group hans */ public function testMorph(): void { $user = User::create(['name' => 'John Doe']); From b44f591b61dc5a0f09dba89e93e46b794d0032a4 Mon Sep 17 00:00:00 2001 From: Mohammad Mortazavi Date: Mon, 6 Nov 2023 16:17:49 +0330 Subject: [PATCH 05/13] Fix phpcs; --- src/Eloquent/HybridRelations.php | 2 +- tests/RelationsTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Eloquent/HybridRelations.php b/src/Eloquent/HybridRelations.php index 9de518200..17d569c4b 100644 --- a/src/Eloquent/HybridRelations.php +++ b/src/Eloquent/HybridRelations.php @@ -212,7 +212,7 @@ public function morphTo($name = null, $type = null, $id = null, $ownerKey = null [$type, $id] = $this->getMorphs(Str::snake($name), $type, $id); - if ($ownerKey === null){ + if ($ownerKey === null) { $ownerKey = $this->getKeyName(); } diff --git a/tests/RelationsTest.php b/tests/RelationsTest.php index 0114c6cc1..f8cfda4f1 100644 --- a/tests/RelationsTest.php +++ b/tests/RelationsTest.php @@ -481,7 +481,7 @@ public function testMorph(): void $this->assertEquals($client->_id, $photo->hasImage->_id); // inverse with custom ownerKey - $photo = Photo::query()->create(['cphoto_id'=>(string)(new ObjectId()), 'url' => 'https://graph.facebook.com/young.gerald/picture']); + $photo = Photo::query()->create(['cphoto_id' => (string) (new ObjectId()), 'url' => 'https://graph.facebook.com/young.gerald/picture']); $client = Client::create(['name' => 'Young Gerald']); $photo->hasImage()->associate($client)->save(); From 3728b1f1b94f91453ab22077d895c96d061402e9 Mon Sep 17 00:00:00 2001 From: Mohammad Mortazavi Date: Mon, 6 Nov 2023 17:32:34 +0330 Subject: [PATCH 06/13] keyName of queried model as default ownerKey; --- src/Relations/MorphTo.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Relations/MorphTo.php b/src/Relations/MorphTo.php index 53b93f8d7..762e40806 100644 --- a/src/Relations/MorphTo.php +++ b/src/Relations/MorphTo.php @@ -16,7 +16,8 @@ public function addConstraints() // For belongs to relationships, which are essentially the inverse of has one // or has many relationships, we need to actually query on the primary key // of the related models matching on the foreign key that's on a parent. - $this->query->where($this->ownerKey, '=', $this->parent->{$this->foreignKey}); + $this->query->where($this->ownerKey ?: $this->query->getModel()->getKeyName(), '=', + $this->parent->{$this->foreignKey}); } } From 6b35c88cdc5c9f1a3a99c4b90c0a6cde4ecc4e29 Mon Sep 17 00:00:00 2001 From: Mohammad Mortazavi Date: Mon, 6 Nov 2023 17:33:37 +0330 Subject: [PATCH 07/13] Update test; --- tests/Models/Photo.php | 2 +- tests/RelationsTest.php | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/Models/Photo.php b/tests/Models/Photo.php index b7f7d6b26..74852dc28 100644 --- a/tests/Models/Photo.php +++ b/tests/Models/Photo.php @@ -20,6 +20,6 @@ public function hasImage(): MorphTo public function hasImageWithCustomOwnerKey(): MorphTo { - return $this->morphTo(ownerKey: 'cphoto_id'); + return $this->morphTo(ownerKey: 'cclient_id'); } } diff --git a/tests/RelationsTest.php b/tests/RelationsTest.php index f8cfda4f1..44a9f24c7 100644 --- a/tests/RelationsTest.php +++ b/tests/RelationsTest.php @@ -481,13 +481,14 @@ public function testMorph(): void $this->assertEquals($client->_id, $photo->hasImage->_id); // inverse with custom ownerKey - $photo = Photo::query()->create(['cphoto_id' => (string) (new ObjectId()), 'url' => 'https://graph.facebook.com/young.gerald/picture']); - $client = Client::create(['name' => 'Young Gerald']); - $photo->hasImage()->associate($client)->save(); - - $this->assertCount(1, $photo->hasImage()->get()); - $this->assertInstanceOf(Client::class, $photo->hasImage); - $this->assertEquals($client->_id, $photo->hasImage->_id); + $photo = Photo::query()->create([ 'url' => 'https://graph.facebook.com/young.gerald/picture']); + $client = Client::create(['cclient_id' => (string) (new ObjectId()),'name' => 'Young Gerald']); + $photo->hasImageWithCustomOwnerKey()->associate($client)->save(); + + $this->assertCount(1, $photo->hasImageWithCustomOwnerKey()->get()); + $this->assertInstanceOf(Client::class, $photo->hasImageWithCustomOwnerKey); + $this->assertEquals($client->cclient_id, $photo->has_image_with_custom_owner_key_id); + $this->assertEquals($client->_id, $photo->hasImageWithCustomOwnerKey->_id); } public function testHasManyHas(): void From a1d89277e1727350b13e3c8348effa2dd1217315 Mon Sep 17 00:00:00 2001 From: Mohammad Mortazavi Date: Mon, 6 Nov 2023 17:37:20 +0330 Subject: [PATCH 08/13] Revert "KeyName as default value for ownerKey;" This reverts commit 54c9a859 --- src/Eloquent/HybridRelations.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Eloquent/HybridRelations.php b/src/Eloquent/HybridRelations.php index 17d569c4b..9e11605a3 100644 --- a/src/Eloquent/HybridRelations.php +++ b/src/Eloquent/HybridRelations.php @@ -212,10 +212,6 @@ public function morphTo($name = null, $type = null, $id = null, $ownerKey = null [$type, $id] = $this->getMorphs(Str::snake($name), $type, $id); - if ($ownerKey === null) { - $ownerKey = $this->getKeyName(); - } - // If the type value is null it is probably safe to assume we're eager loading // the relationship. When that is the case we will pass in a dummy query as // there are multiple types in the morph and we can't use single queries. From 0f00ab76a379c7599cfc6be375a2961dece0fb6d Mon Sep 17 00:00:00 2001 From: Mohammad Mortazavi Date: Mon, 6 Nov 2023 17:59:42 +0330 Subject: [PATCH 09/13] Fix phpcs; --- src/Relations/MorphTo.php | 7 +++++-- tests/RelationsTest.php | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Relations/MorphTo.php b/src/Relations/MorphTo.php index 762e40806..8ce7e9196 100644 --- a/src/Relations/MorphTo.php +++ b/src/Relations/MorphTo.php @@ -16,8 +16,11 @@ public function addConstraints() // For belongs to relationships, which are essentially the inverse of has one // or has many relationships, we need to actually query on the primary key // of the related models matching on the foreign key that's on a parent. - $this->query->where($this->ownerKey ?: $this->query->getModel()->getKeyName(), '=', - $this->parent->{$this->foreignKey}); + $this->query->where( + $this->ownerKey ?: $this->query->getModel()->getKeyName(), + '=', + $this->parent->{$this->foreignKey}, + ); } } diff --git a/tests/RelationsTest.php b/tests/RelationsTest.php index 44a9f24c7..a4a1c7a84 100644 --- a/tests/RelationsTest.php +++ b/tests/RelationsTest.php @@ -481,8 +481,8 @@ public function testMorph(): void $this->assertEquals($client->_id, $photo->hasImage->_id); // inverse with custom ownerKey - $photo = Photo::query()->create([ 'url' => 'https://graph.facebook.com/young.gerald/picture']); - $client = Client::create(['cclient_id' => (string) (new ObjectId()),'name' => 'Young Gerald']); + $photo = Photo::query()->create(['url' => 'https://graph.facebook.com/young.gerald/picture']); + $client = Client::create(['cclient_id' => (string) (new ObjectId()), 'name' => 'Young Gerald']); $photo->hasImageWithCustomOwnerKey()->associate($client)->save(); $this->assertCount(1, $photo->hasImageWithCustomOwnerKey()->get()); From 423a706b43ae96cda7539d161ca9be017f0d4e35 Mon Sep 17 00:00:00 2001 From: Mohammad Mortazavi Date: Tue, 7 Nov 2023 13:40:56 +0330 Subject: [PATCH 10/13] Update MorphTo.php --- src/Relations/MorphTo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Relations/MorphTo.php b/src/Relations/MorphTo.php index 8ce7e9196..1eff5e53b 100644 --- a/src/Relations/MorphTo.php +++ b/src/Relations/MorphTo.php @@ -17,9 +17,9 @@ public function addConstraints() // or has many relationships, we need to actually query on the primary key // of the related models matching on the foreign key that's on a parent. $this->query->where( - $this->ownerKey ?: $this->query->getModel()->getKeyName(), + $this->ownerKey, '=', - $this->parent->{$this->foreignKey}, + $this->getForeignKeyFrom($this->parent), ); } } From 4c03ea820280c8d412d7a31e6d12a794cc928408 Mon Sep 17 00:00:00 2001 From: Mohammad Mortazavi Date: Tue, 7 Nov 2023 13:46:58 +0330 Subject: [PATCH 11/13] Default value for ownerKey; --- src/Eloquent/HybridRelations.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Eloquent/HybridRelations.php b/src/Eloquent/HybridRelations.php index 9e11605a3..d779e086e 100644 --- a/src/Eloquent/HybridRelations.php +++ b/src/Eloquent/HybridRelations.php @@ -221,7 +221,7 @@ public function morphTo($name = null, $type = null, $id = null, $ownerKey = null $this->newQuery(), $this, $id, - $ownerKey, + $ownerKey ?: $this->getKeyName(), $type, $name, ); From 73ecd41ec11afad8b2f9904f6cdbc8b74516d552 Mon Sep 17 00:00:00 2001 From: Mohammad Mortazavi Date: Tue, 7 Nov 2023 13:47:54 +0330 Subject: [PATCH 12/13] Check if the related model is original; --- src/Eloquent/HybridRelations.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Eloquent/HybridRelations.php b/src/Eloquent/HybridRelations.php index d779e086e..0d6f809e2 100644 --- a/src/Eloquent/HybridRelations.php +++ b/src/Eloquent/HybridRelations.php @@ -236,6 +236,11 @@ public function morphTo($name = null, $type = null, $id = null, $ownerKey = null $ownerKey ??= $instance->getKeyName(); + // Check if it is a relation with an original model. + if (! is_subclass_of($instance, MongoDBModel::class)) { + return parent::morphTo($name,$type,$id,$ownerKey); + } + return new MorphTo( $instance->newQuery(), $this, From 6966abb1d7f6201fd6420f94960830691e8ee831 Mon Sep 17 00:00:00 2001 From: Mohammad Mortazavi Date: Tue, 7 Nov 2023 13:49:51 +0330 Subject: [PATCH 13/13] Fix phpcs; --- src/Eloquent/HybridRelations.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Eloquent/HybridRelations.php b/src/Eloquent/HybridRelations.php index 0d6f809e2..f0824c9fb 100644 --- a/src/Eloquent/HybridRelations.php +++ b/src/Eloquent/HybridRelations.php @@ -238,7 +238,7 @@ public function morphTo($name = null, $type = null, $id = null, $ownerKey = null // Check if it is a relation with an original model. if (! is_subclass_of($instance, MongoDBModel::class)) { - return parent::morphTo($name,$type,$id,$ownerKey); + return parent::morphTo($name, $type, $id, $ownerKey); } return new MorphTo(