<?php
namespace PHPFUI\PayPal;
abstract class Base
{
protected static array $validFields = [];
private array $data = [];
private static array $scalars = [
'boolean' => true,
'double' => true,
'integer' => true,
'string' => true,
];
private array $setFields = [];
public function __construct()
{
foreach (static::$validFields as $field => $type)
{
if (! \is_array($type) && ! isset(self::$scalars[$type]))
{
$this->data[$field] = new $type();
}
}
}
public function __get(string $field) : mixed
{
if (! isset(static::$validFields[$field]))
{
throw new \Exception("{$field} is not a valid field for " . static::class);
}
$this->setFields[$field] = true;
return $this->data[$field] ?? null;
}
public function __set(string $field, mixed $value) : void
{
$expectedType = static::$validFields[$field] ?? null;
if (null === $expectedType)
{
throw new \Exception("{$field} is not a valid field for " . static::class);
}
$type = \gettype($value);
if ('object' == $type)
{
$type = $value::class;
}
if (\is_array($expectedType))
{
if (! \in_array($value, $expectedType))
{
throw new \Exception("{$field} is {$value} but must be one of " . \implode(', ', $expectedType) . ' for ' . static::class);
}
}
elseif ($expectedType != $type)
{
throw new \Exception("{$field} is of type {$type} but should be type {$expectedType} for " . static::class);
}
switch ($type)
{
case 'string':
$value = \substr($value, 0, 127);
break;
case 'double':
$value = \number_format($value, 2);
break;
}
$this->setFields[$field] = true;
$this->data[$field] = $value;
}
public function getData() : array
{
$result = [];
foreach ($this->data as $field => $value)
{
if (! empty($this->setFields[$field]))
{
if ('object' == \gettype($value))
{
$value = $value->getData();
}
$result[$field] = $value;
}
}
return $result;
}
public function getJSON() : string
{
return \json_encode($this->getData(), JSON_PRETTY_PRINT);
}
public function getValidFields() : array
{
return static::$validFields;
}
}