This repository has been archived by the owner on Nov 1, 2022. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 186
/
Copy pathDataTransferObject.php
125 lines (92 loc) · 3.15 KB
/
DataTransferObject.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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, $property->getDefaultValue()));
$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;
}
}