How to cast a property in the DTO class of Spatie\DataTransferObject

2.4k Views Asked by At

In laravel I have used spatie/data-transfer-object to cast one of my column as

protected $casts = [
    'details' => ProductDetails::class,    
];

In my ProductDetails DTO I further want to cast two of my date fields

class ProductDetails extends CastableDataTransferObject
{
    use HasDates;

    public int $number

    #[CastWith(ProductDateCaster::class)]
    public int $start_date; //est DD/MM/YY

    #[CastWith(ProductDateCaster::class)]
    public int $end_date;

}

Here is my Caster

class ProductDateCaster implements Caster{
    
  public function cast(mixed $value): string
        {
            $productDetails = new ProductDetails();
            return $productDetails->parseDate($value)->format('d/m/Y');
        }
    }

I'm not doing it the right way, the caster is creating an object of DTO and is providing null to fields other than casted one. Can anyone please suggest the right way for using a caster on specific fields of DTO

1

There are 1 best solutions below

0
Ajax Test On

Use the example blew as a starting point '?' is null safe for PHP8 always use that.

class UserDto extends DataTransferObject
{
    public string $email;
    public ?string $password = null;

    public ?int $city_id                      = null;
    public ?array $about                      = ['en'=>'','ar'=>''];


public ?bool $fromAdmin = null;


public function __construct($args)
{
    parent::__construct($args);
}


/**
 * @throws UnknownProperties
 */
public static function userModel(Request $params): Self
{
    return new self([
        'email'     => $params->input('email'),
        'password'  => $params->filled('password') ? bcrypt($params->input('password')) : false,
        'city_id' => $params?->input('city_id'),

        'about'   => [
            'en' => $params?->input('about')['en'] ?? NULL,
            'ar' => $params?->input('about')['ar'] ?? NULL,
        ],

        'fromAdmin' => $params?->input('fromAdmin'),

        
    ]);
}

}