dep: DTO
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\DataTransferObject;
|
||||
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
use Spatie\DataTransferObject\Attributes\CastWith;
|
||||
use Spatie\DataTransferObject\Attributes\MapTo;
|
||||
use Spatie\DataTransferObject\Casters\DataTransferObjectCaster;
|
||||
use Spatie\DataTransferObject\Exceptions\UnknownProperties;
|
||||
use Spatie\DataTransferObject\Reflection\DataTransferObjectClass;
|
||||
|
||||
#[CastWith(DataTransferObjectCaster::class)]
|
||||
abstract class DataTransferObject
|
||||
{
|
||||
protected array $exceptKeys = [];
|
||||
|
||||
protected array $onlyKeys = [];
|
||||
|
||||
public function __construct(...$args)
|
||||
{
|
||||
if (is_array($args[0] ?? null)) {
|
||||
$args = $args[0];
|
||||
}
|
||||
|
||||
$class = new DataTransferObjectClass($this);
|
||||
|
||||
foreach ($class->getProperties() as $property) {
|
||||
$property->setValue(Arr::get($args, $property->name) ?? $this->{$property->name} ?? null);
|
||||
|
||||
$args = Arr::forget($args, $property->name);
|
||||
}
|
||||
|
||||
if ($class->isStrict() && count($args)) {
|
||||
throw UnknownProperties::new(static::class, array_keys($args));
|
||||
}
|
||||
|
||||
$class->validate();
|
||||
}
|
||||
|
||||
public static function arrayOf(array $arrayOfParameters): array
|
||||
{
|
||||
return array_map(
|
||||
fn (mixed $parameters) => new static($parameters),
|
||||
$arrayOfParameters
|
||||
);
|
||||
}
|
||||
|
||||
public function all(): array
|
||||
{
|
||||
$data = [];
|
||||
|
||||
$class = new ReflectionClass(static::class);
|
||||
|
||||
$properties = $class->getProperties(ReflectionProperty::IS_PUBLIC);
|
||||
|
||||
foreach ($properties as $property) {
|
||||
if ($property->isStatic()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$mapToAttribute = $property->getAttributes(MapTo::class);
|
||||
$name = count($mapToAttribute) ? $mapToAttribute[0]->newInstance()->name : $property->getName();
|
||||
|
||||
$data[$name] = $property->getValue($this);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function only(string ...$keys): static
|
||||
{
|
||||
$dataTransferObject = clone $this;
|
||||
|
||||
$dataTransferObject->onlyKeys = [...$this->onlyKeys, ...$keys];
|
||||
|
||||
return $dataTransferObject;
|
||||
}
|
||||
|
||||
public function except(string ...$keys): static
|
||||
{
|
||||
$dataTransferObject = clone $this;
|
||||
|
||||
$dataTransferObject->exceptKeys = [...$this->exceptKeys, ...$keys];
|
||||
|
||||
return $dataTransferObject;
|
||||
}
|
||||
|
||||
public function clone(...$args): static
|
||||
{
|
||||
return new static(...array_merge($this->toArray(), $args));
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
if (count($this->onlyKeys)) {
|
||||
$array = Arr::only($this->all(), $this->onlyKeys);
|
||||
} else {
|
||||
$array = Arr::except($this->all(), $this->exceptKeys);
|
||||
}
|
||||
|
||||
$array = $this->parseArray($array);
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
protected function parseArray(array $array): array
|
||||
{
|
||||
foreach ($array as $key => $value) {
|
||||
if ($value instanceof DataTransferObject) {
|
||||
$array[$key] = $value->toArray();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! is_array($value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$array[$key] = $this->parseArray($value);
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user