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; } }