diff --git a/src/Illuminate/Database/Eloquent/Casts/AsUri.php b/src/Illuminate/Database/Eloquent/Casts/AsUri.php new file mode 100644 index 000000000000..d55c6d7996b5 --- /dev/null +++ b/src/Illuminate/Database/Eloquent/Casts/AsUri.php @@ -0,0 +1,32 @@ + + */ + public static function castUsing(array $arguments) + { + return new class implements CastsAttributes + { + public function get($model, $key, $value, $attributes) + { + return isset($value) ? new Uri($value) : null; + } + + public function set($model, $key, $value, $attributes) + { + return isset($value) ? (string) $value : null; + } + }; + } +} diff --git a/tests/Database/DatabaseEloquentModelTest.php b/tests/Database/DatabaseEloquentModelTest.php index d7f6f1538b72..ceceeb08cfd4 100755 --- a/tests/Database/DatabaseEloquentModelTest.php +++ b/tests/Database/DatabaseEloquentModelTest.php @@ -28,6 +28,7 @@ use Illuminate\Database\Eloquent\Casts\AsEnumCollection; use Illuminate\Database\Eloquent\Casts\AsHtmlString; use Illuminate\Database\Eloquent\Casts\AsStringable; +use Illuminate\Database\Eloquent\Casts\AsUri; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Concerns\HasUlids; @@ -49,6 +50,7 @@ use Illuminate\Support\HtmlString; use Illuminate\Support\InteractsWithTime; use Illuminate\Support\Stringable; +use Illuminate\Support\Uri; use InvalidArgumentException; use LogicException; use Mockery as m; @@ -284,6 +286,24 @@ public function testDirtyOnCastedHtmlString() $this->assertTrue($model->isDirty('asHtmlStringAttribute')); } + public function testDirtyOnCastedUri() + { + $model = new EloquentModelCastingStub; + $model->setRawAttributes([ + 'asUriAttribute' => 'https://www.example.com:1234?query=param&another=value', + ]); + $model->syncOriginal(); + + $this->assertInstanceOf(Uri::class, $model->asUriAttribute); + $this->assertFalse($model->isDirty('asUriAttribute')); + + $model->asUriAttribute = new Uri('https://www.example.com:1234?query=param&another=value'); + $this->assertFalse($model->isDirty('asUriAttribute')); + + $model->asUriAttribute = new Uri('https://www.updated.com:1234?query=param&another=value'); + $this->assertTrue($model->isDirty('asUriAttribute')); + } + // public function testDirtyOnCastedEncryptedCollection() // { // $this->encrypter = m::mock(Encrypter::class); @@ -3733,6 +3753,7 @@ protected function casts(): array 'asarrayobjectAttribute' => AsArrayObject::class, 'asStringableAttribute' => AsStringable::class, 'asHtmlStringAttribute' => AsHtmlString::class, + 'asUriAttribute' => AsUri::class, 'asCustomCollectionAttribute' => AsCollection::using(CustomCollection::class), 'asEncryptedArrayObjectAttribute' => AsEncryptedArrayObject::class, 'asEncryptedCustomCollectionAttribute' => AsEncryptedCollection::using(CustomCollection::class),