PHP Spatie DTOs with sub arrays

2k Views Asked by At

I'm trying to implement an endpoint for the Audd audio detection API (callback with a result), using Spatie's Data Transfer Object package for PHP. For this, I have a PlayDTO, which has a PlayResultDTO attribute, which in turn should have an array of PlayTrackDTOs as a sub-attribute:

// PlayDTO.php
namespace App\DTO\Play;
use Spatie\DataTransferObject\DataTransferObject;

class PlayDTO extends DataTransferObject
{
    public string $status;
    public PlayResultDTO $result;
}

//PlayResultDTO.php
namespace App\DTO\Play;
use Spatie\DataTransferObject\DataTransferObject;
class PlayResultDTO extends DataTransferObject
{
    public int $radio_id;
    public string $timestamp;
    public int $play_length;
    /** @var PlayTrackDTO[] */
    #[CastWith(ArrayCaster::class, itemType: PlayTrackDTO::class)]
    public array $results;
}

// PlayTrackDTO.php
namespace App\DTO\Play;
use Spatie\DataTransferObject\DataTransferObject;
class PlayTrackDTO extends DataTransferObject
{
    public string $artist;
    public string $title;
    public string $album;
    public string $release_date;
    public string $label;
    public int $score;
    public string $song_link;
}

When I pass a valid array of data to my PlayDTO constructor, in the newly instaitated PlayDTO class, $result correctly has type PlayResultDTO, but in that $result it's $results attribute is just a simple array of keyed-arrays, when it should be an array of PlayTrackDTO objects.

As far as I can see I followed the guide correctly. I have the most up to date version of the package installed, as well as using PHP8. Would anyone have any suggestions? Thanks

1

There are 1 best solutions below

0
Sargis Avetyan On

You need to use the CastWith class form Spatie Attributes. Also, you are using ArrayCaster, so you need to use that as well.

use Spatie\DataTransferObject\Casters\ArrayCaster;
use Spatie\DataTransferObject\Attributes\CastWith;