Created
June 16, 2021 13:18
-
-
Save gmorel/2fe5599847a420c8f8a4d52ee137afb1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Common\UI\Normalizer; | |
use Doctrine\Common\Util\ClassUtils; | |
/** | |
* Normalize a DTO into a JSON payload. | |
* | |
* @author Guillaume MOREL <[email protected]> | |
*/ | |
class Normalizer | |
{ | |
private NormalizerContainer $normalizerContainer; | |
private array $defaultOptions = []; | |
public function __construct(NormalizerContainer $normalizerContainer) | |
{ | |
$this->normalizerContainer = $normalizerContainer; | |
} | |
/** | |
* @param mixed $value | |
*/ | |
public function addDefaultOption(string $key, $value) | |
{ | |
$this->defaultOptions[$key] = $value; | |
} | |
public function setDefaultsOptions(array $defaultOptions = []) | |
{ | |
$this->defaultOptions = $defaultOptions; | |
} | |
/** | |
* @param array|object|null $data | |
* | |
* @return mixed | |
*/ | |
public function normalize($data, array $options = [], Normalizer $defaultNormalizer = null) | |
{ | |
$options = \array_merge($this->defaultOptions, $options); | |
if (\is_object($data)) { | |
if (null !== $defaultNormalizer) { | |
$normalizer = $defaultNormalizer; | |
} elseif ($this->normalizerContainer->isSupportingEntity($class = ClassUtils::getClass($data))) { | |
$normalizer = $this->normalizerContainer | |
->get($class, isset($options['payload']) ? $options['payload'] : 'default'); | |
} elseif ($data instanceof \Traversable) { | |
return $this->normalizeArray($data, $options, $defaultNormalizer); | |
} else { | |
$normalizer = $data; | |
} | |
$dto = null; | |
if ($normalizer instanceof DTOTransformerInterface) { | |
$dtoClass = $normalizer->getDTOClass(); | |
$dto = new $dtoClass(); | |
} | |
if (null === $dto) { | |
$dto = $normalizer; | |
} | |
if ($normalizer instanceof RestTransformerInterface) { | |
$normalizer->transform($dto, $data, $this, $options); | |
} | |
return $dto; | |
} elseif (\is_array($data) || $data instanceof \Traversable) { | |
return $this->normalizeArray($data, $options, $defaultNormalizer); | |
} | |
return $data; | |
} | |
private function normalizeArray(array $data, array $options = [], Normalizer $defaultNormalizer = null): array | |
{ | |
foreach ($data as $k => $value) { | |
$data[$k] = $this->normalize($value, $options, $defaultNormalizer); | |
} | |
return $data; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment