Skip to content

Commit 13247e1

Browse files
authored
[8.x] Custom cast string into Stringable (#39410)
* custom cast string to stringable * fix ci style * styleci
1 parent 506de15 commit 13247e1

File tree

3 files changed

+68
-5
lines changed

3 files changed

+68
-5
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace Illuminate\Database\Eloquent\Casts;
4+
5+
use Illuminate\Contracts\Database\Eloquent\Castable;
6+
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
7+
use Illuminate\Support\Str;
8+
9+
class AsStringable implements Castable
10+
{
11+
/**
12+
* Get the caster class to use when casting from / to this cast target.
13+
*
14+
* @param array $arguments
15+
* @return object|string
16+
*/
17+
public static function castUsing(array $arguments)
18+
{
19+
return new class implements CastsAttributes
20+
{
21+
public function get($model, $key, $value, $attributes)
22+
{
23+
return isset($value) ? Str::of($value) : null;
24+
}
25+
26+
public function set($model, $key, $value, $attributes)
27+
{
28+
return isset($value) ? (string) $value : null;
29+
}
30+
};
31+
}
32+
}

tests/Database/DatabaseEloquentModelTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Illuminate\Database\Eloquent\Casts\ArrayObject;
1717
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
1818
use Illuminate\Database\Eloquent\Casts\AsCollection;
19+
use Illuminate\Database\Eloquent\Casts\AsStringable;
1920
use Illuminate\Database\Eloquent\Collection;
2021
use Illuminate\Database\Eloquent\JsonEncodingException;
2122
use Illuminate\Database\Eloquent\MassAssignmentException;
@@ -28,6 +29,8 @@
2829
use Illuminate\Support\Carbon;
2930
use Illuminate\Support\Collection as BaseCollection;
3031
use Illuminate\Support\InteractsWithTime;
32+
use Illuminate\Support\Str;
33+
use Illuminate\Support\Stringable;
3134
use InvalidArgumentException;
3235
use LogicException;
3336
use Mockery as m;
@@ -194,6 +197,24 @@ public function testDirtyOnCastedCollection()
194197
$this->assertTrue($model->isDirty('ascollectionAttribute'));
195198
}
196199

200+
public function testDirtyOnCastedStringable()
201+
{
202+
$model = new EloquentModelCastingStub;
203+
$model->setRawAttributes([
204+
'asStringableAttribute' => 'foo bar',
205+
]);
206+
$model->syncOriginal();
207+
208+
$this->assertInstanceOf(Stringable::class, $model->asStringableAttribute);
209+
$this->assertFalse($model->isDirty('asStringableAttribute'));
210+
211+
$model->asStringableAttribute = Str::of('foo bar');
212+
$this->assertFalse($model->isDirty('asStringableAttribute'));
213+
214+
$model->asStringableAttribute = Str::of('foo baz');
215+
$this->assertTrue($model->isDirty('asStringableAttribute'));
216+
}
217+
197218
public function testCleanAttributes()
198219
{
199220
$model = new EloquentModelStub(['foo' => '1', 'bar' => 2, 'baz' => 3]);
@@ -2611,6 +2632,7 @@ class EloquentModelCastingStub extends Model
26112632
'timestampAttribute' => 'timestamp',
26122633
'asarrayobjectAttribute' => AsArrayObject::class,
26132634
'ascollectionAttribute' => AsCollection::class,
2635+
'asStringableAttribute' => AsStringable::class,
26142636
];
26152637

26162638
public function jsonAttributeValue()
Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,45 @@
44

55
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
66
use Illuminate\Database\Eloquent\Casts\AsCollection;
7+
use Illuminate\Database\Eloquent\Casts\AsStringable;
78
use Illuminate\Database\Eloquent\Model;
89
use Illuminate\Database\Schema\Blueprint;
910
use Illuminate\Support\Facades\Schema;
11+
use Illuminate\Support\Str;
1012

11-
class DatabaseArrayObjectAndCollectionCustomCastTest extends DatabaseTestCase
13+
/**
14+
* @group integration
15+
*/
16+
class DatabaseCustomCastsTest extends DatabaseTestCase
1217
{
1318
protected function setUp(): void
1419
{
1520
parent::setUp();
1621

17-
Schema::create('test_eloquent_model_with_custom_array_object_casts', function (Blueprint $table) {
22+
Schema::create('test_eloquent_model_with_custom_casts', function (Blueprint $table) {
1823
$table->increments('id');
1924
$table->text('array_object');
2025
$table->text('collection');
26+
$table->string('stringable');
2127
$table->timestamps();
2228
});
2329
}
2430

25-
public function test_array_object_and_collection_casting()
31+
public function test_custom_casting()
2632
{
27-
$model = new TestEloquentModelWithCustomArrayObjectCast;
33+
$model = new TestEloquentModelWithCustomCasts;
2834

2935
$model->array_object = ['name' => 'Taylor'];
3036
$model->collection = collect(['name' => 'Taylor']);
37+
$model->stringable = Str::of('Taylor');
3138

3239
$model->save();
3340

3441
$model = $model->fresh();
3542

3643
$this->assertEquals(['name' => 'Taylor'], $model->array_object->toArray());
3744
$this->assertEquals(['name' => 'Taylor'], $model->collection->toArray());
45+
$this->assertEquals('Taylor', (string) $model->stringable);
3846

3947
$model->array_object['age'] = 34;
4048
$model->array_object['meta']['title'] = 'Developer';
@@ -51,7 +59,7 @@ public function test_array_object_and_collection_casting()
5159
}
5260
}
5361

54-
class TestEloquentModelWithCustomArrayObjectCast extends Model
62+
class TestEloquentModelWithCustomCasts extends Model
5563
{
5664
/**
5765
* The attributes that aren't mass assignable.
@@ -68,5 +76,6 @@ class TestEloquentModelWithCustomArrayObjectCast extends Model
6876
protected $casts = [
6977
'array_object' => AsArrayObject::class,
7078
'collection' => AsCollection::class,
79+
'stringable' => AsStringable::class,
7180
];
7281
}

0 commit comments

Comments
 (0)