Skip to content

Instantly share code, notes, and snippets.

@gmorel
Created June 16, 2021 13:18
Show Gist options
  • Save gmorel/2fe5599847a420c8f8a4d52ee137afb1 to your computer and use it in GitHub Desktop.
Save gmorel/2fe5599847a420c8f8a4d52ee137afb1 to your computer and use it in GitHub Desktop.
<?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 <me@gmorel.io>
*/
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