From ca9783c84e4f70c2dc5b443eb5a06a0dc8ee3977 Mon Sep 17 00:00:00 2001 From: Ahmed Bally Date: Thu, 7 Sep 2023 20:47:25 +0300 Subject: [PATCH 1/3] Support Route Scope Binding --- src/Traits/OptimusEncodedRouteKey.php | 25 +++++++++++++++++++ ...07_173419_add_parent_id_to_users_table.php | 23 +++++++++++++++++ .../UserWithCustomOptimusConnection.php | 13 ++++++++++ .../UserWithDefaultOptimusConnection.php | 12 +++++++++ tests/Traits/OptimusEncodedRouteKeyTest.php | 19 +++++++++++--- 5 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 tests/Stubs/Migrations/2023_09_07_173419_add_parent_id_to_users_table.php diff --git a/src/Traits/OptimusEncodedRouteKey.php b/src/Traits/OptimusEncodedRouteKey.php index 748ead3..a74f75d 100644 --- a/src/Traits/OptimusEncodedRouteKey.php +++ b/src/Traits/OptimusEncodedRouteKey.php @@ -40,6 +40,31 @@ public function resolveRouteBinding($value, $field = null) return $this->where($field, $value)->first(); } + /** + * Retrieve the model for a bound value. + * + * @param \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Relations\Relation $query + * @param mixed $value + * @param string|null $field + * @return \Illuminate\Database\Eloquent\Relations\Relation + */ + public function resolveRouteBindingQuery($query, $value, $field = null) + { + if ($field === null) { + $field = $query->getRouteKeyName(); + } + + if (is_string($value) && ctype_digit($value)) { + $value = (int) $value; + } + + if (is_int($value) && $field === $this->getRouteKeyName()) { + $value = $this->getOptimus()->decode($value); + } + + return $query->where($field ?? $this->getRouteKeyName(), $value); + } + /** * Get the Optimus instance. * diff --git a/tests/Stubs/Migrations/2023_09_07_173419_add_parent_id_to_users_table.php b/tests/Stubs/Migrations/2023_09_07_173419_add_parent_id_to_users_table.php new file mode 100644 index 0000000..cf3cf78 --- /dev/null +++ b/tests/Stubs/Migrations/2023_09_07_173419_add_parent_id_to_users_table.php @@ -0,0 +1,23 @@ +foreignId('parent_id') + ->nullable(); + }); + } + + public function down() + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn(['parent_id']); + }); + } +} diff --git a/tests/Stubs/Models/UserWithCustomOptimusConnection.php b/tests/Stubs/Models/UserWithCustomOptimusConnection.php index 6d45cbf..2161afa 100644 --- a/tests/Stubs/Models/UserWithCustomOptimusConnection.php +++ b/tests/Stubs/Models/UserWithCustomOptimusConnection.php @@ -4,6 +4,8 @@ use Cog\Laravel\Optimus\Traits\OptimusEncodedRouteKey; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; final class UserWithCustomOptimusConnection extends Model { @@ -14,4 +16,15 @@ final class UserWithCustomOptimusConnection extends Model protected $table = 'users'; protected $guarded = []; + + + public function nestedUsers(): HasMany + { + return $this->hasMany(UserWithCustomOptimusConnection::class, 'parent_id'); + } + + public function parentUser(): BelongsTo + { + return$this->belongsTo(UserWithCustomOptimusConnection::class, 'parent_id'); + } } diff --git a/tests/Stubs/Models/UserWithDefaultOptimusConnection.php b/tests/Stubs/Models/UserWithDefaultOptimusConnection.php index 080c487..7db30cc 100644 --- a/tests/Stubs/Models/UserWithDefaultOptimusConnection.php +++ b/tests/Stubs/Models/UserWithDefaultOptimusConnection.php @@ -4,6 +4,8 @@ use Cog\Laravel\Optimus\Traits\OptimusEncodedRouteKey; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; final class UserWithDefaultOptimusConnection extends Model { @@ -12,4 +14,14 @@ final class UserWithDefaultOptimusConnection extends Model protected $table = 'users'; protected $guarded = []; + + public function nestedUsers(): HasMany + { + return $this->hasMany(UserWithDefaultOptimusConnection::class, 'parent_id'); + } + + public function parentUser(): BelongsTo + { + return$this->belongsTo(UserWithDefaultOptimusConnection::class, 'parent_id'); + } } diff --git a/tests/Traits/OptimusEncodedRouteKeyTest.php b/tests/Traits/OptimusEncodedRouteKeyTest.php index ce566b7..cd931c6 100644 --- a/tests/Traits/OptimusEncodedRouteKeyTest.php +++ b/tests/Traits/OptimusEncodedRouteKeyTest.php @@ -28,6 +28,7 @@ protected function setUp(): void parent::setUp(); $this->loadLaravelMigrations(config('database.default')); + $this->loadMigrationsFrom(__DIR__.'/../Stubs/Migrations'); $this->configurePrimeNumbers(); } @@ -51,6 +52,18 @@ public function testOptimusConnectionCanBeConfigured(): void $this->assertNotEquals($incorrectEncodedId, $routeKey); } + public function testResolveChildRouteWithEncodedKey(): void + { + $user = $this->createUserWithDefaultOptimusConnection(); + $nestedUser = $this->createUserWithDefaultOptimusConnection([ + 'email' => 'test1@user.com' + ]); + $nestedUser->parentUser()->associate($user)->save(); + $resolvedNestedUser = $user->resolveChildRouteBinding('nested_user', $nestedUser->getRouteKey(), 'id'); + + $this->assertEquals($nestedUser->id, $resolvedNestedUser->id); + } + public function testResolveModelWithEncodedKey(): void { $user = $this->createUserWithDefaultOptimusConnection(); @@ -172,13 +185,13 @@ public function testExistingIntegerValuesBelow256AreResolved() * * @return \Cog\Tests\Laravel\Optimus\Stubs\Models\UserWithDefaultOptimusConnection */ - protected function createUserWithDefaultOptimusConnection(): UserWithDefaultOptimusConnection + protected function createUserWithDefaultOptimusConnection(array $data = []): UserWithDefaultOptimusConnection { - return UserWithDefaultOptimusConnection::create([ + return UserWithDefaultOptimusConnection::create(array_merge([ 'name' => 'Default Test User', 'email' => 'test@user.com', 'password' => 'p4ssw0rd', - ]); + ], $data)); } /** From 88799c449153f761f1976a3b44842e8d66388767 Mon Sep 17 00:00:00 2001 From: Ahmed Bally Date: Thu, 7 Sep 2023 21:12:01 +0300 Subject: [PATCH 2/3] fix style --- tests/Stubs/Models/UserWithCustomOptimusConnection.php | 1 - tests/Traits/OptimusEncodedRouteKeyTest.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/Stubs/Models/UserWithCustomOptimusConnection.php b/tests/Stubs/Models/UserWithCustomOptimusConnection.php index 2161afa..4671516 100644 --- a/tests/Stubs/Models/UserWithCustomOptimusConnection.php +++ b/tests/Stubs/Models/UserWithCustomOptimusConnection.php @@ -17,7 +17,6 @@ final class UserWithCustomOptimusConnection extends Model protected $guarded = []; - public function nestedUsers(): HasMany { return $this->hasMany(UserWithCustomOptimusConnection::class, 'parent_id'); diff --git a/tests/Traits/OptimusEncodedRouteKeyTest.php b/tests/Traits/OptimusEncodedRouteKeyTest.php index cd931c6..45daa4f 100644 --- a/tests/Traits/OptimusEncodedRouteKeyTest.php +++ b/tests/Traits/OptimusEncodedRouteKeyTest.php @@ -56,7 +56,7 @@ public function testResolveChildRouteWithEncodedKey(): void { $user = $this->createUserWithDefaultOptimusConnection(); $nestedUser = $this->createUserWithDefaultOptimusConnection([ - 'email' => 'test1@user.com' + 'email' => 'test1@user.com', ]); $nestedUser->parentUser()->associate($user)->save(); $resolvedNestedUser = $user->resolveChildRouteBinding('nested_user', $nestedUser->getRouteKey(), 'id'); From b209359cf595d0b78acceba0e753cb4dbf424148 Mon Sep 17 00:00:00 2001 From: Ahmed Bally Date: Mon, 11 Sep 2023 02:27:12 +0300 Subject: [PATCH 3/3] fix where clause for route key. --- src/Traits/OptimusEncodedRouteKey.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Traits/OptimusEncodedRouteKey.php b/src/Traits/OptimusEncodedRouteKey.php index a74f75d..ee93801 100644 --- a/src/Traits/OptimusEncodedRouteKey.php +++ b/src/Traits/OptimusEncodedRouteKey.php @@ -62,7 +62,7 @@ public function resolveRouteBindingQuery($query, $value, $field = null) $value = $this->getOptimus()->decode($value); } - return $query->where($field ?? $this->getRouteKeyName(), $value); + return $query->where($field, $value); } /**