vendor/api-platform/core/src/Core/Identifier/IdentifierConverter.php line 66

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the API Platform project.
  4.  *
  5.  * (c) Kévin Dunglas <dunglas@gmail.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. declare(strict_types=1);
  11. namespace ApiPlatform\Core\Identifier;
  12. use ApiPlatform\Core\Api\IdentifiersExtractorInterface;
  13. use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
  14. use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
  15. use ApiPlatform\Exception\InvalidIdentifierException;
  16. use Symfony\Component\PropertyInfo\Type;
  17. use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
  18. /**
  19.  * Identifier converter that chains identifier denormalizers.
  20.  *
  21.  * @author Antoine Bluchet <soyuka@gmail.com>
  22.  */
  23. final class IdentifierConverter implements ContextAwareIdentifierConverterInterface
  24. {
  25.     private $propertyMetadataFactory;
  26.     private $identifiersExtractor;
  27.     private $identifierDenormalizers;
  28.     private $resourceMetadataFactory;
  29.     /**
  30.      * TODO: rename identifierDenormalizers to identifierTransformers in 3.0 and change their interfaces to a IdentifierTransformerInterface.
  31.      *
  32.      * @param iterable<DenormalizerInterface> $identifierDenormalizers
  33.      */
  34.     public function __construct(IdentifiersExtractorInterface $identifiersExtractor, PropertyMetadataFactoryInterface $propertyMetadataFactory, iterable $identifierDenormalizers, ResourceMetadataFactoryInterface $resourceMetadataFactory = null)
  35.     {
  36.         $this->propertyMetadataFactory = $propertyMetadataFactory;
  37.         $this->identifiersExtractor = $identifiersExtractor;
  38.         $this->identifierDenormalizers = $identifierDenormalizers;
  39.         $this->resourceMetadataFactory = $resourceMetadataFactory;
  40.     }
  41.     /**
  42.      * {@inheritdoc}
  43.      */
  44.     public function convert($data, string $class, array $context = []): array
  45.     {
  46.         if (!\is_array($data)) {
  47.             @trigger_error(sprintf('Not using an array as the first argument of "%s->convert" is deprecated since API Platform 2.6 and will not be possible anymore in API Platform 3', self::class), \E_USER_DEPRECATED);
  48.             $data = ['id' => $data];
  49.         }
  50.         $identifiers = $data;
  51.         foreach ($data as $parameter => $value) {
  52.             if (null === $type = $this->getIdentifierType($context['identifiers'][$parameter][0] ?? $class, $context['identifiers'][$parameter][1] ?? $parameter)) {
  53.                 continue;
  54.             }
  55.             /* @var DenormalizerInterface[] */
  56.             foreach ($this->identifierDenormalizers as $identifierTransformer) {
  57.                 if (!$identifierTransformer->supportsDenormalization($value, $type)) {
  58.                     continue;
  59.                 }
  60.                 try {
  61.                     $identifiers[$parameter] = $identifierTransformer->denormalize($value, $type);
  62.                     break;
  63.                 } catch (InvalidIdentifierException $e) { // @phpstan-ignore-line wrong choice of interface, was fixed in 3.0
  64.                     throw new InvalidIdentifierException(sprintf('Identifier "%s" could not be denormalized.', $parameter), $e->getCode(), $e);
  65.                 }
  66.             }
  67.         }
  68.         return $identifiers;
  69.     }
  70.     private function getIdentifierType(string $resourceClass, string $property): ?string
  71.     {
  72.         if (!$type = $this->propertyMetadataFactory->create($resourceClass, $property)->getType()) {
  73.             return null;
  74.         }
  75.         return Type::BUILTIN_TYPE_OBJECT === ($builtinType = $type->getBuiltinType()) ? $type->getClassName() : $builtinType;
  76.     }
  77. }