Skip to content

Instantly share code, notes, and snippets.

@Gummibeer
Created November 9, 2022 19:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gummibeer/2a418a0cdc928e5cc5036446820d0f87 to your computer and use it in GitHub Desktop.
Save Gummibeer/2a418a0cdc928e5cc5036446820d0f87 to your computer and use it in GitHub Desktop.
<?php
namespace Astrotomic\FogTradeSdk\Concerns;
use Astrotomic\FogTradeSdk\Attributes\CastToData;
use BadMethodCallException;
use ReflectionAttribute;
use ReflectionClass;
use Sammyjo20\Saloon\Http\SaloonResponse;
use Sammyjo20\Saloon\Traits\Plugins\CastsToDto as SaloonCastsToDto;
use Spatie\LaravelData\Contracts\BaseData;
use Spatie\LaravelData\Contracts\BaseDataCollectable;
trait CastsToDto
{
use SaloonCastsToDto;
protected function castToDto(SaloonResponse $response): BaseData|BaseDataCollectable
{
$class = new ReflectionClass(static::class);
/** @var CastToData|null $attribute */
$attribute = collect($class->getAttributes())
->map(fn (ReflectionAttribute $reflectionAttribute) => $reflectionAttribute->newInstance())
->first(fn (object $attribute) => $attribute instanceof CastToData);
if ($attribute === null) {
throw new BadMethodCallException();
}
$class = $attribute->class;
$interfaces = class_implements($class);
$items = $response->json($attribute->key);
return match (true) {
in_array(BaseData::class, $interfaces) => $class::from($items),
in_array(BaseDataCollectable::class, $interfaces) => new $class(
dataClass: $attribute->dataClass,
items: $items
),
};
}
}
<?php
namespace Astrotomic\FogTradeSdk\Attributes;
use Attribute;
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_PROPERTY)]
class CastToData
{
public function __construct(
/** @var class-string<\Spatie\LaravelData\Contracts\BaseData|\Spatie\LaravelData\Contracts\BaseDataCollectable> $dataClass */
public readonly string $class,
public readonly string|null $dataClass = null,
public readonly string|null $key = null,
) {
}
}
<?php
namespace Astrotomic\FogTradeSdk\Requests;
use Astrotomic\FogTradeSdk\Attributes\CastToData;
use Astrotomic\FogTradeSdk\Concerns\CastsToDto;
use Sammyjo20\Saloon\Http\SaloonRequest;
use Spatie\LaravelData\DataCollection;
#[CastToData(DataCollection::class, dataClass: Appeal::class, key: 'data')]
class Request extends SaloonRequest
{
use CastsToDto;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment