Skip to content

Commit

Permalink
[8.x] Custom cast string into Stringable (#39410)
Browse files Browse the repository at this point in the history
* custom cast string to stringable

* fix ci style

* styleci
  • Loading branch information
louisgab authored Oct 29, 2021
1 parent 506de15 commit 13247e1
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 5 deletions.
32 changes: 32 additions & 0 deletions src/Illuminate/Database/Eloquent/Casts/AsStringable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Illuminate\Database\Eloquent\Casts;

use Illuminate\Contracts\Database\Eloquent\Castable;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Support\Str;

class AsStringable implements Castable
{
/**
* Get the caster class to use when casting from / to this cast target.
*
* @param array $arguments
* @return object|string
*/
public static function castUsing(array $arguments)
{
return new class implements CastsAttributes
{
public function get($model, $key, $value, $attributes)
{
return isset($value) ? Str::of($value) : null;
}

public function set($model, $key, $value, $attributes)
{
return isset($value) ? (string) $value : null;
}
};
}
}
22 changes: 22 additions & 0 deletions tests/Database/DatabaseEloquentModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Illuminate\Database\Eloquent\Casts\ArrayObject;
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
use Illuminate\Database\Eloquent\Casts\AsCollection;
use Illuminate\Database\Eloquent\Casts\AsStringable;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\JsonEncodingException;
use Illuminate\Database\Eloquent\MassAssignmentException;
Expand All @@ -28,6 +29,8 @@
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection as BaseCollection;
use Illuminate\Support\InteractsWithTime;
use Illuminate\Support\Str;
use Illuminate\Support\Stringable;
use InvalidArgumentException;
use LogicException;
use Mockery as m;
Expand Down Expand Up @@ -194,6 +197,24 @@ public function testDirtyOnCastedCollection()
$this->assertTrue($model->isDirty('ascollectionAttribute'));
}

public function testDirtyOnCastedStringable()
{
$model = new EloquentModelCastingStub;
$model->setRawAttributes([
'asStringableAttribute' => 'foo bar',
]);
$model->syncOriginal();

$this->assertInstanceOf(Stringable::class, $model->asStringableAttribute);
$this->assertFalse($model->isDirty('asStringableAttribute'));

$model->asStringableAttribute = Str::of('foo bar');
$this->assertFalse($model->isDirty('asStringableAttribute'));

$model->asStringableAttribute = Str::of('foo baz');
$this->assertTrue($model->isDirty('asStringableAttribute'));
}

public function testCleanAttributes()
{
$model = new EloquentModelStub(['foo' => '1', 'bar' => 2, 'baz' => 3]);
Expand Down Expand Up @@ -2611,6 +2632,7 @@ class EloquentModelCastingStub extends Model
'timestampAttribute' => 'timestamp',
'asarrayobjectAttribute' => AsArrayObject::class,
'ascollectionAttribute' => AsCollection::class,
'asStringableAttribute' => AsStringable::class,
];

public function jsonAttributeValue()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,45 @@

use Illuminate\Database\Eloquent\Casts\AsArrayObject;
use Illuminate\Database\Eloquent\Casts\AsCollection;
use Illuminate\Database\Eloquent\Casts\AsStringable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;

class DatabaseArrayObjectAndCollectionCustomCastTest extends DatabaseTestCase
/**
* @group integration
*/
class DatabaseCustomCastsTest extends DatabaseTestCase
{
protected function setUp(): void
{
parent::setUp();

Schema::create('test_eloquent_model_with_custom_array_object_casts', function (Blueprint $table) {
Schema::create('test_eloquent_model_with_custom_casts', function (Blueprint $table) {
$table->increments('id');
$table->text('array_object');
$table->text('collection');
$table->string('stringable');
$table->timestamps();
});
}

public function test_array_object_and_collection_casting()
public function test_custom_casting()
{
$model = new TestEloquentModelWithCustomArrayObjectCast;
$model = new TestEloquentModelWithCustomCasts;

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

$model->save();

$model = $model->fresh();

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

$model->array_object['age'] = 34;
$model->array_object['meta']['title'] = 'Developer';
Expand All @@ -51,7 +59,7 @@ public function test_array_object_and_collection_casting()
}
}

class TestEloquentModelWithCustomArrayObjectCast extends Model
class TestEloquentModelWithCustomCasts extends Model
{
/**
* The attributes that aren't mass assignable.
Expand All @@ -68,5 +76,6 @@ class TestEloquentModelWithCustomArrayObjectCast extends Model
protected $casts = [
'array_object' => AsArrayObject::class,
'collection' => AsCollection::class,
'stringable' => AsStringable::class,
];
}

0 comments on commit 13247e1

Please sign in to comment.