chill-bundles/src/Bundle/ChillMainBundle/Serializer/Normalizer/DiscriminatedObjectDenormalizer.php

78 lines
2.4 KiB
PHP

<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chill\MainBundle\Serializer\Normalizer;
use LogicException;
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
use Symfony\Component\Serializer\Exception\RuntimeException;
use Symfony\Component\Serializer\Normalizer\ContextAwareDenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait;
use function count;
use function implode;
/**
* Denormalize an object given a list of supported class.
*/
class DiscriminatedObjectDenormalizer implements ContextAwareDenormalizerInterface, DenormalizerAwareInterface
{
use DenormalizerAwareTrait;
/**
* Should be present in context and contains an array of
* allowed types.
*/
public const ALLOWED_TYPES = 'denormalize_multi.allowed_types';
/**
* The type to set for enabling this type.
*/
public const TYPE = '@multi';
public function denormalize($data, $type, $format = null, array $context = [])
{
foreach ($context[self::ALLOWED_TYPES] as $localType) {
if ($this->denormalizer->supportsDenormalization($data, $localType, $format)) {
try {
return $this->denormalizer->denormalize($data, $localType, $format, $context);
} catch (RuntimeException|NotNormalizableValueException $e) {
$lastException = $e;
}
}
}
throw new RuntimeException(sprintf('Could not find any denormalizer for those ' .
'ALLOWED_TYPES: %s', implode(', ', $context[self::ALLOWED_TYPES])));
}
public function supportsDenormalization($data, $type, $format = null, array $context = [])
{
if (self::TYPE !== $type) {
return false;
}
if (0 === count($context[self::ALLOWED_TYPES] ?? [])) {
throw new LogicException('The context should contains a list of
allowed types');
}
foreach ($context[self::ALLOWED_TYPES] as $localType) {
if ($this->denormalizer->supportsDenormalization($data, $localType, $format)) {
return true;
}
}
return false;
}
}