This commit is contained in:
2022-01-24 03:22:03 +09:00
parent d75f21035d
commit 290e7ee05e
34 changed files with 1936 additions and 8 deletions
@@ -0,0 +1,70 @@
<?php
namespace Spatie\DataTransferObject\Casters;
use ArrayAccess;
use LogicException;
use Spatie\DataTransferObject\Caster;
use Traversable;
class ArrayCaster implements Caster
{
public function __construct(
private array $types,
private string $itemType,
) {
}
public function cast(mixed $value): array | ArrayAccess
{
foreach ($this->types as $type) {
if ($type == 'array') {
return $this->mapInto(
destination: [],
items: $value
);
}
if (is_subclass_of($type, ArrayAccess::class)) {
return $this->mapInto(
destination: new $type(),
items: $value
);
}
}
throw new LogicException(
"Caster [ArrayCaster] may only be used to cast arrays or objects that implement ArrayAccess."
);
}
private function mapInto(array | ArrayAccess $destination, mixed $items): array | ArrayAccess
{
if ($destination instanceof ArrayAccess && ! is_subclass_of($destination, Traversable::class)) {
throw new LogicException(
"Caster [ArrayCaster] may only be used to cast ArrayAccess objects that are traversable."
);
}
foreach ($items as $key => $item) {
$destination[$key] = $this->castItem($item);
}
return $destination;
}
private function castItem(mixed $data)
{
if ($data instanceof $this->itemType) {
return $data;
}
if (is_array($data)) {
return new $this->itemType(...$data);
}
throw new LogicException(
"Caster [ArrayCaster] each item must be an array or an instance of the specified item type [{$this->itemType}]."
);
}
}
@@ -0,0 +1,25 @@
<?php
namespace Spatie\DataTransferObject\Casters;
use Spatie\DataTransferObject\Caster;
use Spatie\DataTransferObject\DataTransferObject;
class DataTransferObjectCaster implements Caster
{
public function __construct(
private array $classNames
) {
}
public function cast(mixed $value): DataTransferObject
{
foreach ($this->classNames as $className) {
if ($value instanceof $className) {
return $value;
}
}
return new $this->classNames[0](...$value);
}
}